我想裁剪和调整图片的大小。 这里是我的代码:
Image image = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "Cropper/tests/castle.jpg");
// Crop and resize the image.
Rectangle destination = new Rectangle(0, 0, 200, 120);
Graphics graphic = Graphics.FromImage(image);
graphic.DrawImage(image, destination, int.Parse(X1.Value), int.Parse(Y1.Value), int.Parse(Width.Value), int.Parse(Height.Value), GraphicsUnit.Pixel);
现在假设,在图形对象我产生裁剪/调整图像存储。 现在的问题是 - 如何将其保存到一个文件?
该Graphics
对象,您得到Graphics.FromImage
是图像的绘图表面。 所以,你可以简单地将图像保存对象时,你就完成了。
string fileName = AppDomain.CurrentDomain.BaseDirectory + "Cropper/tests/castle.jpg");
using (Image image = Image.FromFile(fileName)
{
using (Graphics graphic = Graphics.FromImage(image))
{
// Crop and resize the image.
Rectangle destination = new Rectangle(0, 0, 200, 120);
graphic.DrawImage(image, destination, int.Parse(X1.Value), int.Parse(Y1.Value), int.Parse(Width.Value), int.Parse(Height.Value), GraphicsUnit.Pixel);
}
image.Save(fileName);
}
但是要注意一个jpg图像上反复这样做未必是好事; 图像被重新编码每个时间和自JPG采用了破坏性的压缩方法,你每次都会失去一些图像质量。 我不会担心,如果这是一次每个图像的操作虽然。
不, Graphics
对象不包含任何图像数据,它是用来绘制的帆布,这通常是屏幕或对Bitmap
对象。
所以,你需要创建一个Bitmap
与正确的尺寸对象可借鉴,并创建Graphics
对象为位图。 然后,你可以将它保存。 请记住,对象实施IDisposable
应设置,例如使用using
子句:
using (Image image = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "Cropper/tests/castle.jpg")) {
// Create bitmap
using (Bitmap newImage = new Bitmap(200, 120)) {
// Crop and resize the image.
Rectangle destination = new Rectangle(0, 0, 200, 120);
using (Graphics graphic = Graphics.FromImage(newImage)) {
graphic.DrawImage(image, destination, int.Parse(X1.Value), int.Parse(Y1.Value), int.Parse(Width.Value), int.Parse(Height.Value), GraphicsUnit.Pixel);
}
newImage.Save(AppDomain.CurrentDomain.BaseDirectory + "Cropper/tests/castle_icon.jpg", ImageFormat.Jpeg);
}
}
这不是一个直接的答案OP的问题,但它是一个经常被忽视的工具,它可以让你对待事物以不同的方式,应该是证明有必要。
人们常常说,这是不可能得到在图形对象的内容。 这是不正确的。 有了正确的方法,你可以利用HDC和BitBlt的画布上访问数据。 下面是用C#做这件事:
enum TernaryRasterOperations : uint
{
/// <summary>dest = source</summary>
SRCCOPY = 0x00CC0020,
/// <summary>dest = source OR dest</summary>
SRCPAINT = 0x00EE0086,
/// <summary>dest = source AND dest</summary>
SRCAND = 0x008800C6,
/// <summary>dest = source XOR dest</summary>
SRCINVERT = 0x00660046,
/// <summary>dest = source AND (NOT dest)</summary>
SRCERASE = 0x00440328,
/// <summary>dest = (NOT source)</summary>
NOTSRCCOPY = 0x00330008,
/// <summary>dest = (NOT src) AND (NOT dest)</summary>
NOTSRCERASE = 0x001100A6,
/// <summary>dest = (source AND pattern)</summary>
MERGECOPY = 0x00C000CA,
/// <summary>dest = (NOT source) OR dest</summary>
MERGEPAINT = 0x00BB0226,
/// <summary>dest = pattern</summary>
PATCOPY = 0x00F00021,
/// <summary>dest = DPSnoo</summary>
PATPAINT = 0x00FB0A09,
/// <summary>dest = pattern XOR dest</summary>
PATINVERT = 0x005A0049,
/// <summary>dest = (NOT dest)</summary>
DSTINVERT = 0x00550009,
/// <summary>dest = BLACK</summary>
BLACKNESS = 0x00000042,
/// <summary>dest = WHITE</summary>
WHITENESS = 0x00FF0062,
/// <summary>
/// Capture window as seen on screen. This includes layered windows
/// such as WPF windows with AllowsTransparency="true"
/// </summary>
CAPTUREBLT = 0x40000000
}
[DllImport("gdi32.dll", EntryPoint = "BitBlt", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool BitBlt([In] IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, [In] IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);
public static Bitmap CopyGraphicsContent(Graphics source, Rectangle rect)
{
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
using (Graphics dest = Graphics.FromImage(bmp))
{
IntPtr hdcSource = source.GetHdc();
IntPtr hdcDest = dest.GetHdc();
BitBlt(hdcDest, 0, 0, rect.Width, rect.Height, hdcSource, rect.X, rect.Y, TernaryRasterOperations.SRCCOPY);
source.ReleaseHdc(hdcSource);
dest.ReleaseHdc(hdcDest);
}
return bmp;
}