Comment puis-je recadrer une image en utilisant C#?
D'accord, mais notez que si la cropArea traverse la frontière de l'image, cela génère une exception "Mémoire insuffisante".
Comment puis-je recadrer une image en utilisant C#?
Découvrez ce lien : http://www.switchonthecode.com/tutorials/csharp-tutorial-image-editing-saving-cropping-and-resizing
private static Image cropImage(Image img, Rectangle cropArea)
{
Bitmap bmpImage = new Bitmap(img);
return bmpImage.Clone(cropArea, bmpImage.PixelFormat);
}
D'accord, mais notez que si la cropArea traverse la frontière de l'image, cela génère une exception "Mémoire insuffisante".
@KvanTTT, les deux sont assez lents si vous voulez recadrer une grande image en plusieurs petites.
Vous pouvez utiliser [Graphics.DrawImage
][1] pour dessiner une image recadrée sur l'objet graphics à partir d'un bitmap.
Rectangle cropRect = new Rectangle(...);
using (Bitmap src = Image.FromFile("") as Bitmap)
{
using (Bitmap target = new Bitmap(cropRect.Width, cropRect.Height))
{
using (Graphics g = Graphics.FromImage(target))
{
g.DrawImage(src, new Rectangle(0, 0, target.Width, target.Height),
cropRect,
GraphicsUnit.Pixel);
}
}
}
Juste une note, la signature de DrawImage() n'est pas valide. Il manque le paramètre GraphicsUnit.
Plus simple que la réponse acceptée est celle-ci :
public static Bitmap cropAtRect(this Bitmap b, Rectangle r)
{
using (var nb = new Bitmap(r.Width, r.Height))
{
using (Graphics g = Graphics.FromImage(nb))
{
g.DrawImage(b, -r.X, -r.Y);
return nb;
}
}
}
et cela évite le risque d'exception "Out of memory" de la réponse la plus simple.
Notez que Bitmap
et Graphics
sont IDisposable
donc les clauses using
.
MODIFICATION : Je trouve que cela fonctionne bien avec les PNG enregistrés par Bitmap.Save
ou Paint.exe, mais échoue avec les PNG enregistrés par exemple avec Paint Shop Pro 6 - le contenu est déplacé. L'ajout de GraphicsUnit.Pixel
donne un résultat incorrect différent. Peut-être que juste ces PNG défaillants sont défectueux.
Meilleure réponse ici, cela devrait être récompensé comme réponse. J'avais également rencontré le problème de 'mémoire insuffisante' avec d'autres solutions. Cela a fonctionné du premier coup.
Je ne comprends pas pourquoi l'ajout de GraphicsUnit.Pixel donne le mauvais résultat, mais c'est certainement le cas.
Mes images étaient rognées avec la bonne taille mais à un mauvais X/Y jusqu'à ce que j'appelle SetResolution sur l'image cible comme suggéré dans la réponse de @IntellyDev.
utilisez
bmp.SetResolution(image.HorizontalResolution, image.VerticalResolution);
cela peut être nécessaire à faire même si vous implémentez la meilleure réponse ici surtout si votre image est vraiment grande et que les résolutions ne sont pas exactement de 96.0
Mon exemple de test:
static Bitmap LoadImage()
{
return (Bitmap)Bitmap.FromFile( @"e:\Tests\d_bigImage.bmp" ); // ici une grande image de 9222x9222 pixels et une résolution de 95.96 dpi
}
static void TestBigImagePartDrawing()
{
using( var absentRectangleImage = LoadImage() )
{
using( var currentTile = new Bitmap( 256, 256 ) )
{
currentTile.SetResolution(absentRectangleImage.HorizontalResolution, absentRectangleImage.VerticalResolution);
using( var currentTileGraphics = Graphics.FromImage( currentTile ) )
{
currentTileGraphics.Clear( Color.Black );
var absentRectangleArea = new Rectangle( 3, 8963, 256, 256 );
currentTileGraphics.DrawImage( absentRectangleImage, 0, 0, absentRectangleArea, GraphicsUnit.Pixel );
}
currentTile.Save(@"e:\Tests\Tile.bmp");
}
}
}
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
Je viens de créer une classe personnalisée pour simplement recadrer tout contrôle qui a une image ou une image de fond. Je l'ai téléchargée sur github.com : github.com/DwainSnickles/ControlCrop/blob/master/README.md