J'ai récemment été confronté au problème du recadrage et du redimensionnement des images. Je devais recadrer le « contenu principal » d'une image par exemple si j'avais une image semblable à ceci: alt text http://blstb.msn.com/i/8C/10F73EB7EE231B1EA8E65EFA7D69B.jpgComment déterminer les bords d'une image de manière optimale?
le résultat devrait être une image avec le contenu msn sans les marges blanches (gauche & droite).
Je recherche la même chose sur l'axe X pour le premier et le dernier changement de couleur et sur l'axe Y. Le problème est que traverser l'image ligne par ligne prend un certain temps ... pour une image qui est 2000x1600px cela prend jusqu'à 2 secondes pour retourner les données CropRect => x1, y1, x2, y2.
J'ai essayé de faire pour chaque coordonnée une traversée et un arrêt sur la première valeur trouvée mais cela n'a pas fonctionné dans tous les cas de test ... parfois les données retournées n'étaient pas celles attendues et la durée des opérations était similaire
Une idée de comment réduire le temps de traversée et la découverte du rectangle autour du 'contenu principal'?
public static CropRect EdgeDetection(Bitmap Image, float Threshold)
{
CropRect cropRectangle = new CropRect();
int lowestX = 0;
int lowestY = 0;
int largestX = 0;
int largestY = 0;
lowestX = Image.Width;
lowestY = Image.Height;
//find the lowest X bound;
for (int y = 0; y < Image.Height - 1; ++y)
{
for (int x = 0; x < Image.Width - 1; ++x)
{
Color currentColor = Image.GetPixel(x, y);
Color tempXcolor = Image.GetPixel(x + 1, y);
Color tempYColor = Image.GetPixel(x, y + 1);
if ((Math.Sqrt(((currentColor.R - tempXcolor.R) * (currentColor.R - tempXcolor.R)) +
((currentColor.G - tempXcolor.G) * (currentColor.G - tempXcolor.G)) +
((currentColor.B - tempXcolor.B) * (currentColor.B - tempXcolor.B))) > Threshold))
{
if (lowestX > x)
lowestX = x;
if (largestX < x)
largestX = x;
}
if ((Math.Sqrt(((currentColor.R - tempYColor.R) * (currentColor.R - tempYColor.R)) +
((currentColor.G - tempYColor.G) * (currentColor.G - tempYColor.G)) +
((currentColor.B - tempYColor.B) * (currentColor.B - tempYColor.B))) > Threshold))
{
if (lowestY > y)
lowestY = y;
if (largestY < y)
largestY = y;
}
}
}
if (lowestX < Image.Width/4)
cropRectangle.X = lowestX - 3 > 0 ? lowestX - 3 : 0;
else
cropRectangle.X = 0;
if (lowestY < Image.Height/4)
cropRectangle.Y = lowestY - 3 > 0 ? lowestY - 3 : 0;
else
cropRectangle.Y = 0;
cropRectangle.Width = largestX - lowestX + 8 > Image.Width ? Image.Width : largestX - lowestX + 8;
cropRectangle.Height = largestY + 8 > Image.Height ? Image.Height - lowestY : largestY - lowestY + 8;
return cropRectangle;
}
}
Quelle que soit votre optimisation je collerais un Debug.Assert (content! = Null) ... lire dans ce que vous allez :-) –