2009-07-30 10 views
0

J'ai écrit une méthode pour recadrer des images en C#. Il le fait en créant un nouveau bitmap et en dessinant sur lui un rectangle spécifié (la zone à recadrer) de l'image originale. Pour les images que j'ai essayées, cela produisait des résultats erronés. La taille de l'image résultante était correcte, mais le contenu l'était. C'était comme si l'image avait été agrandie de 2 puis recadrée. Finalement, l'ajout de cette ligne l'a corrigé:Pourquoi dois-je spécifier une résolution à recadrer?

result.setResolution(72, 72) 

Mais pourquoi ai-je besoin d'une résolution? Je travaille avec des pixels, jamais avec des pouces ou des centimètres. Aussi, quelle serait alors la bonne résolution?

Le code complet est cette méthode d'extension:

public static Bitmap Crop(this Image image, int x, int y, int width, int height) { 
    Bitmap result = new Bitmap(width, height); 
    result.SetResolution(72, 72); 

    // Use a graphics object to draw the resized image into the bitmap. 
    using (Graphics graphics = Graphics.FromImage(result)) { 
     // High quality. 
     graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 
     graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
     graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 
     // Draw the image into the target bitmap. 
     graphics.DrawImage(image, 0, 0, new Rectangle(x, y, width, height), GraphicsUnit.Pixel); 
    } 

    return result; 
} 

Répondre

1

Vous utilisez la surcharge incorrecte de DrawImage. Vous devriez utiliser celui où vous spécifiez les renvois Src et Dest.

graphics.DrawImage(image, new Rectangle(0, 0, width, height), new Rectangle(x, y, width, height), GraphicsUnit.Pixel); 

Essayez-le et faites-moi savoir dans les commentaires si cela ne fonctionne pas.

-1

Je soupçonne que la réponse réside dans la façon dont la bibliothèque fait effectivement la modification. il suffit de copier et coller autour de quelques blocs de mémoire. la résolution spécifie le nombre de bits/octets utilisés par pixel. Pour savoir combien d'octets il doit copier, il doit savoir combien de bits/octets par pixel sont utilisés.

donc je pense que c'est une simple multiplication suivie d'une memcopy.

+0

Le format de l'image ne doit-il pas définir combien d'octets par pixel? Est-ce RVB? RGBA? Sont-ils ints, longs ou flotteurs? Et puis copiez juste les pixels que je lui dis. – Pablo

+0

Eh oui, c'est le cas. mais le format n'a que des informations sur comment stocker les données. Selon le format, il est possible que la résolution soit variable et ne soit donc pas connue précisément par le format. Je suppose que les flotteurs ne s'appliquent pas. De quel type de format s'agit-il? ou est-ce inconnu? Que se passe-t-il si vous omettez la ligne result.SetResolution (72, 72); salutations – Atmocreations

+0

Je pense que les cartes vidéo utilisent RGBA avec des flotteurs. Si j'omets la résolution et disons, je recadre (0, 0, 100, 100) je reçois une image de 100 par 100 avec un morceau de l'image originale d'environ 60 par 60 étiré. – Pablo

Questions connexes