2009-07-18 79 views
8

我想裁剪和調整圖像大小。這裏是我的代碼:圖形對象到圖像文件

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); 

現在我認爲我得到的裁剪/調整後的圖像存儲在圖形對象。問題是 - 如何將其保存到文件?

回答

10

GraphicsGraphics.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使用破壞性壓縮方法,因此每次都會丟失一些圖像質量。不過,如果這是一個每圖像一次的操作,我不會擔心。

5

不,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); 
    } 
} 
1

這不是一個直接的答案OP的問題,但它是一個經常被忽視的工具,它可以讓你接近的東西一個不同的方式,如果證明是必要的。

人們經常說,無法獲取Graphics對象的內容。這根本不是真的。使用正確的方法,您可以使用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; 
    } 
+2

是否回答此問題?請解釋如何回答這個問題 – CocoNess 2018-01-24 13:09:29