10

画像を切り抜いてサイズを変更したいのですが。これが私のコードです:

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

ここで、結果のトリミング/サイズ変更された画像がグラフィックスオブジェクトに保存されていると仮定します。問題は、ファイルに保存するにはどうすればよいですか?

4

3 に答える 3

13

取得する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は破壊的な圧縮方法を使用しているため、毎回画質が低下します。ただし、これがイメージごとに1回の操作である場合は、心配する必要はありません。

于 2009-07-18T10:07:57.780 に答える
7

いいえ、オブジェクトには画像データは含まれていません。通常は画面またはオブジェクト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);
   }
}
于 2009-07-18T11:02:57.277 に答える
4

これはOPの質問に対する直接の答えではありませんが、必要に応じて別の方法で物事に取り組むことができる、見過ごされがちなツールです。

Graphicsオブジェクトのコンテンツを取得することは不可能であるとよく言われます。これはまったく真実ではありません。適切なアプローチを使用すると、HDCとBitBltを使用してキャンバス上のデータにアクセスできます。C#を使用してこれを行う1つの方法は次のとおりです。

    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;
    }
于 2018-01-24T11:22:48.997 に答える