2009-07-18 3 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

Graphics.FromImage에서 가져온 Graphics 개체는 이미지의 그리기 화면입니다. 완료되면 이미지 객체를 간단히 저장할 수 있습니다.

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 개체를 만들어야합니다. 그런 다음 저장할 수 있습니다. using 절 사용 예를 들어, 폐기해야 IDisposable를 구현하는 객체를 기억

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

+0

누구나 Graphics 객체의 내용을 복사 할 수 없다고합니다. 이것은 전혀 사실이 아닙니다. HDC 및 BitBlt를 사용하여 캔버스의 데이터에 액세스 할 수 있습니다. 다음은 C#을 사용하여 수행하는 방법입니다. – user1830791

+0

이것은 내 검색이 OP 질문을 제기했을 때 찾고 있었던 내용입니다. :) –

관련 문제