2009-07-18 11 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は破壊的な圧縮方法を使用するため、毎回イメージ品質が低下します。私はこれが画像ごとに1回の操作であるなら、それについて心配しないでしょう。

5

いいえ、Graphicsオブジェクトにはイメージデータが含まれていません。キャンバス上に描画するために使用されます。キャンバスは通常画面またはBitmapオブジェクトです。

したがって、描画するのに適切なサイズのBitmapオブジェクトを作成し、そのビットマップにGraphicsオブジェクトを作成する必要があります。その後、それを保存することができます。

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の質問に直接答えではないが、それはあなたが物事にアプローチできるようにすることができ、多くの場合、見過ごさツールです:IDisposableを実装し、そのオブジェクトがusing句を使用して、たとえば、廃棄することを忘れないでください別の方法で、それが必要であると証明する必要があります。

多くの場合、Graphicsオブジェクトの内容を取得することはできません。これはまったく真実ではありません。正しいアプローチで、HDCとBitBltを使用してキャンバス上のデータにアクセスできます。

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

これは、C#を使用して行う方法の1つです。これがどのように質問に答えるか説明してください – CocoNess

+0

誰もがGraphicsオブジェクトの内容をコピーすることはできません。これはまったく真実ではありません。 HDCとBitBltを使用して、キャンバス上のデータにアクセスできます。ここではC#を使用してそれを行う方法です。 – user1830791

+0

これは、私の検索で多くの人の間でOPの質問が起きたときに私が探していたものです:) –

関連する問題