C# Move bitmap in picturebox












2














I create image with LockBits from array in cycle and scale to PictureBox.Width * n and Height:



using (var bmp = new Bitmap(len, _height, PixelFormat.Format24bppRgb))
{
var data = bmp.LockBits(new Rectangle(0, 0, len, _height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
var bytes = data.Stride * data.Height;
var rgb = new byte[bytes];
var ptr = data.Scan0;
Marshal.Copy(data.Scan0, rgb, 0, bytes);


// …fill array „rgb“

Marshal.Copy(rgb, 0, ptr, bytes);
bmp.UnlockBits(data);

g = _pictureBox.CreateGraphics();
g.InterpolationMode = InterpolationMode.Default;
g.DrawImage(bmp, _pictureBox.Width - len * _scaleWidth, 0, len * _scaleWidth, _pictureBox.Height);
}


In the next iterateration:



Graphics g;
using (var bmp = new Bitmap(_pictureBox.Image))
{
g = _pictureBox.CreateGraphics();
g.InterpolationMode = InterpolationMode.Default;
g.DrawImage(_pictureBox.Image, new RectangleF(0, 0, _pictureBox.Width - len * _scaleWidth, _pictureBox.Height), new RectangleF(len * _scaleWidth, 0, _pictureBox.Width * _scaleWidth - len, _height), GraphicsUnit.Pixel);
}
g.Dispose();


In short: I cut and copy part of the image that would shift the picture, but do not get anything. Is it possible because of the scale in the previous step?
Maybe I'm wrong. Advise the algorithm for shifting and adding a new Bitmap into an end.










share|improve this question


















  • 1




    You have to assign the Bitmap to the _pictureBox.Image property first, than assigning to it as nessecary. I advice you to use Control.CreateGraphics() method and write on a Form directly.
    – Artur Mustafin
    Sep 20 '11 at 6:44












  • You can pin miage to the mouse pointer, and subscribe to the mouse movements other the bitmap while left button is pressed on a form, by attaching to the MouseClick and MouseMove event on a control, in which you can use my Win32 Interop. I will edit my post to add the sample.
    – Artur Mustafin
    Sep 20 '11 at 7:05
















2














I create image with LockBits from array in cycle and scale to PictureBox.Width * n and Height:



using (var bmp = new Bitmap(len, _height, PixelFormat.Format24bppRgb))
{
var data = bmp.LockBits(new Rectangle(0, 0, len, _height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
var bytes = data.Stride * data.Height;
var rgb = new byte[bytes];
var ptr = data.Scan0;
Marshal.Copy(data.Scan0, rgb, 0, bytes);


// …fill array „rgb“

Marshal.Copy(rgb, 0, ptr, bytes);
bmp.UnlockBits(data);

g = _pictureBox.CreateGraphics();
g.InterpolationMode = InterpolationMode.Default;
g.DrawImage(bmp, _pictureBox.Width - len * _scaleWidth, 0, len * _scaleWidth, _pictureBox.Height);
}


In the next iterateration:



Graphics g;
using (var bmp = new Bitmap(_pictureBox.Image))
{
g = _pictureBox.CreateGraphics();
g.InterpolationMode = InterpolationMode.Default;
g.DrawImage(_pictureBox.Image, new RectangleF(0, 0, _pictureBox.Width - len * _scaleWidth, _pictureBox.Height), new RectangleF(len * _scaleWidth, 0, _pictureBox.Width * _scaleWidth - len, _height), GraphicsUnit.Pixel);
}
g.Dispose();


In short: I cut and copy part of the image that would shift the picture, but do not get anything. Is it possible because of the scale in the previous step?
Maybe I'm wrong. Advise the algorithm for shifting and adding a new Bitmap into an end.










share|improve this question


















  • 1




    You have to assign the Bitmap to the _pictureBox.Image property first, than assigning to it as nessecary. I advice you to use Control.CreateGraphics() method and write on a Form directly.
    – Artur Mustafin
    Sep 20 '11 at 6:44












  • You can pin miage to the mouse pointer, and subscribe to the mouse movements other the bitmap while left button is pressed on a form, by attaching to the MouseClick and MouseMove event on a control, in which you can use my Win32 Interop. I will edit my post to add the sample.
    – Artur Mustafin
    Sep 20 '11 at 7:05














2












2








2


1





I create image with LockBits from array in cycle and scale to PictureBox.Width * n and Height:



using (var bmp = new Bitmap(len, _height, PixelFormat.Format24bppRgb))
{
var data = bmp.LockBits(new Rectangle(0, 0, len, _height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
var bytes = data.Stride * data.Height;
var rgb = new byte[bytes];
var ptr = data.Scan0;
Marshal.Copy(data.Scan0, rgb, 0, bytes);


// …fill array „rgb“

Marshal.Copy(rgb, 0, ptr, bytes);
bmp.UnlockBits(data);

g = _pictureBox.CreateGraphics();
g.InterpolationMode = InterpolationMode.Default;
g.DrawImage(bmp, _pictureBox.Width - len * _scaleWidth, 0, len * _scaleWidth, _pictureBox.Height);
}


In the next iterateration:



Graphics g;
using (var bmp = new Bitmap(_pictureBox.Image))
{
g = _pictureBox.CreateGraphics();
g.InterpolationMode = InterpolationMode.Default;
g.DrawImage(_pictureBox.Image, new RectangleF(0, 0, _pictureBox.Width - len * _scaleWidth, _pictureBox.Height), new RectangleF(len * _scaleWidth, 0, _pictureBox.Width * _scaleWidth - len, _height), GraphicsUnit.Pixel);
}
g.Dispose();


In short: I cut and copy part of the image that would shift the picture, but do not get anything. Is it possible because of the scale in the previous step?
Maybe I'm wrong. Advise the algorithm for shifting and adding a new Bitmap into an end.










share|improve this question













I create image with LockBits from array in cycle and scale to PictureBox.Width * n and Height:



using (var bmp = new Bitmap(len, _height, PixelFormat.Format24bppRgb))
{
var data = bmp.LockBits(new Rectangle(0, 0, len, _height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
var bytes = data.Stride * data.Height;
var rgb = new byte[bytes];
var ptr = data.Scan0;
Marshal.Copy(data.Scan0, rgb, 0, bytes);


// …fill array „rgb“

Marshal.Copy(rgb, 0, ptr, bytes);
bmp.UnlockBits(data);

g = _pictureBox.CreateGraphics();
g.InterpolationMode = InterpolationMode.Default;
g.DrawImage(bmp, _pictureBox.Width - len * _scaleWidth, 0, len * _scaleWidth, _pictureBox.Height);
}


In the next iterateration:



Graphics g;
using (var bmp = new Bitmap(_pictureBox.Image))
{
g = _pictureBox.CreateGraphics();
g.InterpolationMode = InterpolationMode.Default;
g.DrawImage(_pictureBox.Image, new RectangleF(0, 0, _pictureBox.Width - len * _scaleWidth, _pictureBox.Height), new RectangleF(len * _scaleWidth, 0, _pictureBox.Width * _scaleWidth - len, _height), GraphicsUnit.Pixel);
}
g.Dispose();


In short: I cut and copy part of the image that would shift the picture, but do not get anything. Is it possible because of the scale in the previous step?
Maybe I'm wrong. Advise the algorithm for shifting and adding a new Bitmap into an end.







c# bitmap interpolation drawimage lockbits






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Sep 20 '11 at 6:30









Kir

130210




130210








  • 1




    You have to assign the Bitmap to the _pictureBox.Image property first, than assigning to it as nessecary. I advice you to use Control.CreateGraphics() method and write on a Form directly.
    – Artur Mustafin
    Sep 20 '11 at 6:44












  • You can pin miage to the mouse pointer, and subscribe to the mouse movements other the bitmap while left button is pressed on a form, by attaching to the MouseClick and MouseMove event on a control, in which you can use my Win32 Interop. I will edit my post to add the sample.
    – Artur Mustafin
    Sep 20 '11 at 7:05














  • 1




    You have to assign the Bitmap to the _pictureBox.Image property first, than assigning to it as nessecary. I advice you to use Control.CreateGraphics() method and write on a Form directly.
    – Artur Mustafin
    Sep 20 '11 at 6:44












  • You can pin miage to the mouse pointer, and subscribe to the mouse movements other the bitmap while left button is pressed on a form, by attaching to the MouseClick and MouseMove event on a control, in which you can use my Win32 Interop. I will edit my post to add the sample.
    – Artur Mustafin
    Sep 20 '11 at 7:05








1




1




You have to assign the Bitmap to the _pictureBox.Image property first, than assigning to it as nessecary. I advice you to use Control.CreateGraphics() method and write on a Form directly.
– Artur Mustafin
Sep 20 '11 at 6:44






You have to assign the Bitmap to the _pictureBox.Image property first, than assigning to it as nessecary. I advice you to use Control.CreateGraphics() method and write on a Form directly.
– Artur Mustafin
Sep 20 '11 at 6:44














You can pin miage to the mouse pointer, and subscribe to the mouse movements other the bitmap while left button is pressed on a form, by attaching to the MouseClick and MouseMove event on a control, in which you can use my Win32 Interop. I will edit my post to add the sample.
– Artur Mustafin
Sep 20 '11 at 7:05




You can pin miage to the mouse pointer, and subscribe to the mouse movements other the bitmap while left button is pressed on a form, by attaching to the MouseClick and MouseMove event on a control, in which you can use my Win32 Interop. I will edit my post to add the sample.
– Artur Mustafin
Sep 20 '11 at 7:05












2 Answers
2






active

oldest

votes


















1














I advice you to use Control.CreateGraphics() method at Form instance, and write on a Form directly, because PaintBox control is quite slow.



Try using my helper function, this will allow you to paste a portion of your bitmap using StretchBlt (stretching) or BitBlt (no stretching) using Win32 Interop:



Sample usage:



Graphics graphics = ...;
graphics.GdiDrawImage
(
image,
new Rectangle(
(int)rectangle.Left,
(int)rectangle.Top,
(int)rectangle.Width,
(int)rectangle.Height
),
0, 0, image.Width, image.Height
);


Source code:



public static class GraphicsHelper
{
public static void GdiDrawImage(this Graphics graphics, Bitmap image, Rectangle rectangleDst, int nXSrc, int nYSrc, int nWidth, int nHeight)
{
IntPtr hdc = graphics.GetHdc();
IntPtr memdc = GdiInterop.CreateCompatibleDC(hdc);
IntPtr bmp = image.GetHbitmap();
GdiInterop.SelectObject(memdc, bmp);
GdiInterop.SetStretchBltMode(hdc, 0x04);
GdiInterop.StretchBlt(hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, nWidth, nHeight, GdiInterop.TernaryRasterOperations.SRCCOPY);
//GdiInterop.BitBlt(..) put it here, if you did not mention stretching the source image
GdiInterop.DeleteObject(bmp);
GdiInterop.DeleteDC(memdc);
graphics.ReleaseHdc(hdc);
}
}

public class GdiInterop
{
/// <summary>
/// Enumeration for the raster operations used in BitBlt.
/// In C++ these are actually #define. But to use these
/// constants with C#, a new enumeration _type is defined.
/// </summary>
public enum TernaryRasterOperations
{
SRCCOPY = 0x00CC0020, // dest = source
SRCPAINT = 0x00EE0086, // dest = source OR dest
SRCAND = 0x008800C6, // dest = source AND dest
SRCINVERT = 0x00660046, // dest = source XOR dest
SRCERASE = 0x00440328, // dest = source AND (NOT dest)
NOTSRCCOPY = 0x00330008, // dest = (NOT source)
NOTSRCERASE = 0x001100A6, // dest = (NOT src) AND (NOT dest)
MERGECOPY = 0x00C000CA, // dest = (source AND pattern)
MERGEPAINT = 0x00BB0226, // dest = (NOT source) OR dest
PATCOPY = 0x00F00021, // dest = pattern
PATPAINT = 0x00FB0A09, // dest = DPSnoo
PATINVERT = 0x005A0049, // dest = pattern XOR dest
DSTINVERT = 0x00550009, // dest = (NOT dest)
BLACKNESS = 0x00000042, // dest = BLACK
WHITENESS = 0x00FF0062, // dest = WHITE
};

/// <summary>
/// Enumeration to be used for those Win32 function
/// that return BOOL
/// </summary>
public enum Bool
{
False = 0,
True
};

/// <summary>
/// Sets the background color.
/// </summary>
/// <param name="hdc">The HDC.</param>
/// <param name="crColor">Color of the cr.</param>
/// <returns></returns>
[DllImport("gdi32.dll")]
public static extern int SetBkColor(IntPtr hdc, int crColor);

/// <summary>
/// CreateCompatibleDC
/// </summary>
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);

/// <summary>
/// DeleteDC
/// </summary>
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool DeleteDC(IntPtr hdc);

/// <summary>
/// SelectObject
/// </summary>
[DllImport("gdi32.dll", ExactSpelling = true)]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

/// <summary>
/// DeleteObject
/// </summary>
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool DeleteObject(IntPtr hObject);

/// <summary>
/// CreateCompatibleBitmap
/// </summary>
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hObject, int width, int height);

/// <summary>
/// BitBlt
/// </summary>
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

/// <summary>
/// StretchBlt
/// </summary>
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool StretchBlt(IntPtr hObject, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hObjSource, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, TernaryRasterOperations dwRop);

/// <summary>
/// SetStretchBltMode
/// </summary>
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool SetStretchBltMode(IntPtr hObject, int nStretchMode);
}





share|improve this answer























  • GetHbitmap creates a copy of the bitmap data. This may be an issue when using large bitmaps like 10k x 10k RGB, which are around 400MB large: There will be the original Bitmap object of this size and then another "GDI bitmap" of the same size. This will almost never work in a 32 bit process, 64bit is required then: stackoverflow.com/a/11559001
    – Tobias Knauss
    Nov 9 at 16:08



















0














Notice: This is no full answer to the question, but I want to provide some useful information to the existing answer.



In contrast to the answer of Artur Mustafin, I suggest not to use the Windows GDI directly, but to use the .net methods of the Graphics class. In my tests they have performed a lot better than the GDI functions.



The GDI code is taken from the answer of Artur Mustafin.

The test was displaying an image of 1Mpix (1k x 1k) Bitmap or 100Mpix (10k x 10k) Bitmap in 1k x 1k Picturebox by drawing in the Paint event.

The tests were done in Visual Studio 2015.3 on Windows 7 Pro x64 SP1, Debug mode, on an Intel Core i7-3630QM CPU @ 2.4 GHz, 16 GB RAM.



Results:



1000x Graphics.DrawImage() unscaled       of 100M Bitmap:   36.8s (x86),  24.2s (x64).
1000x Graphics.DrawImage() unscaled of 1M Bitmap: 5.2s (x86), 3.8s (x64).
100x Graphics.DrawImage() scaled of 100M Bitmap: 62.8s (x86), 39.0s (x64).
1000x Graphics.DrawImage() scaled of 1M Bitmap: 5.2s (x86), 3.8s (x64).
100x GdiDrawImage() StretchBlockTransfer of 100M Bitmap: OutOfMem@x86, 88.5s (x64).
1000x GdiDrawImage() StretchBlockTransfer of 1M Bitmap: 12.9s (x86), 11.5s (x64).
100x GdiDrawImage() BitBlockTransfer of 100M Bitmap: OutOfMem@x86, 49.7s (x64).
1000x GdiDrawImage() BitBlockTransfer of 1M Bitmap: 7.2s (x86), 5.8s (x64).


Test code:



public partial class FormPictureboxPaint : Form
{
private Bitmap m_oBitmap;

public FormPictureboxPaint ()
{
InitializeComponent ();

string sFile = Application.StartupPath + @"......bitmap.png"; // The bitmap file contains an image with 10k x 10k pixels.
m_oBitmap = new Bitmap (sFile);

if (false) // CHANGE TO TRUE IF TESTING WITH 1k x 1k BITMAPS
{
var oBitmap = new Bitmap (m_oBitmap, new Size (1000, 1000));

m_oBitmap.Dispose ();
m_oBitmap = null;
GC.Collect ();
GC.WaitForFullGCComplete ();
GC.WaitForPendingFinalizers ();

m_oBitmap = oBitmap;
}
}

private void pictureBox1_Paint (object sender, PaintEventArgs e)
{
var oGraphics = e.Graphics;
DateTime dtNow = DateTime.Now;

// UNCOMMENT THE FOLLOWING LINES FOR TESTS WITH DrawImage
// COMMENT THE FOLLOWING LINES FOR TESTS WITH GDI
//for (int ixCnt = 0; ixCnt < 1000; ixCnt++)
// PictureboxPaint01 (oGraphics);

// COMMENT THE FOLLOWING LINES FOR TESTS WITH DrawImage
// UNCOMMENT THE FOLLOWING LINES FOR TESTS WITH GDI
for (int ixCnt = 0; ixCnt < 100; ixCnt++)
PictureboxPaint02 (oGraphics);

TimeSpan ts = (DateTime.Now - dtNow);
}

private void PictureboxPaint01 (Graphics i_oGraphics)
{
//_oGraphics.DrawImage (m_oBitmap, new Point ());
i_oGraphics.DrawImage (m_oBitmap, new Rectangle (0, 0, 1000, 1000));
}

private void PictureboxPaint02 (Graphics i_oGraphics)
{
// from https://stackoverflow.com/a/7481071
i_oGraphics.GdiDrawImage
(
m_oBitmap,
new Rectangle (
(int)pictureBox1.Left,
(int)pictureBox1.Top,
(int)pictureBox1.Width,
(int)pictureBox1.Height
),
0, 0, m_oBitmap.Width, m_oBitmap.Height
);
}
}

public static class GraphicsHelper
{
public static void GdiDrawImage (this Graphics graphics, Bitmap image, Rectangle rectangleDst, int nXSrc, int nYSrc, int nWidth, int nHeight)
{
IntPtr hdc = graphics.GetHdc ();
IntPtr memdc = GdiInterop.CreateCompatibleDC (hdc);
IntPtr bmp = image.GetHbitmap ();
GdiInterop.SelectObject (memdc, bmp);
GdiInterop.SetStretchBltMode (hdc, 0x04);
GdiInterop.StretchBlt (hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, nWidth, nHeight, GdiInterop.TernaryRasterOperations.SRCCOPY);
//GdiInterop.BitBlt (hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, GdiInterop.TernaryRasterOperations.SRCCOPY); //put it here, if you did not mention stretching the source image
GdiInterop.DeleteObject (bmp);
GdiInterop.DeleteDC (memdc);
graphics.ReleaseHdc (hdc);
}
}

public class GdiInterop
{
public enum TernaryRasterOperations
{
SRCCOPY = 0x00CC0020, // dest = source
};

public enum Bool
{
False = 0,
True
};

[DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern IntPtr CreateCompatibleDC (IntPtr hDC);

[DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool DeleteDC (IntPtr hdc);

[DllImport ("gdi32.dll", ExactSpelling = true)]
public static extern IntPtr SelectObject (IntPtr hDC, IntPtr hObject);

[DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool DeleteObject (IntPtr hObject);

[DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool BitBlt (IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

[DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool StretchBlt (IntPtr hObject, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hObjSource, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, TernaryRasterOperations dwRop);

[DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool SetStretchBltMode (IntPtr hObject, int nStretchMode);
}





share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f7481004%2fc-sharp-move-bitmap-in-picturebox%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    I advice you to use Control.CreateGraphics() method at Form instance, and write on a Form directly, because PaintBox control is quite slow.



    Try using my helper function, this will allow you to paste a portion of your bitmap using StretchBlt (stretching) or BitBlt (no stretching) using Win32 Interop:



    Sample usage:



    Graphics graphics = ...;
    graphics.GdiDrawImage
    (
    image,
    new Rectangle(
    (int)rectangle.Left,
    (int)rectangle.Top,
    (int)rectangle.Width,
    (int)rectangle.Height
    ),
    0, 0, image.Width, image.Height
    );


    Source code:



    public static class GraphicsHelper
    {
    public static void GdiDrawImage(this Graphics graphics, Bitmap image, Rectangle rectangleDst, int nXSrc, int nYSrc, int nWidth, int nHeight)
    {
    IntPtr hdc = graphics.GetHdc();
    IntPtr memdc = GdiInterop.CreateCompatibleDC(hdc);
    IntPtr bmp = image.GetHbitmap();
    GdiInterop.SelectObject(memdc, bmp);
    GdiInterop.SetStretchBltMode(hdc, 0x04);
    GdiInterop.StretchBlt(hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, nWidth, nHeight, GdiInterop.TernaryRasterOperations.SRCCOPY);
    //GdiInterop.BitBlt(..) put it here, if you did not mention stretching the source image
    GdiInterop.DeleteObject(bmp);
    GdiInterop.DeleteDC(memdc);
    graphics.ReleaseHdc(hdc);
    }
    }

    public class GdiInterop
    {
    /// <summary>
    /// Enumeration for the raster operations used in BitBlt.
    /// In C++ these are actually #define. But to use these
    /// constants with C#, a new enumeration _type is defined.
    /// </summary>
    public enum TernaryRasterOperations
    {
    SRCCOPY = 0x00CC0020, // dest = source
    SRCPAINT = 0x00EE0086, // dest = source OR dest
    SRCAND = 0x008800C6, // dest = source AND dest
    SRCINVERT = 0x00660046, // dest = source XOR dest
    SRCERASE = 0x00440328, // dest = source AND (NOT dest)
    NOTSRCCOPY = 0x00330008, // dest = (NOT source)
    NOTSRCERASE = 0x001100A6, // dest = (NOT src) AND (NOT dest)
    MERGECOPY = 0x00C000CA, // dest = (source AND pattern)
    MERGEPAINT = 0x00BB0226, // dest = (NOT source) OR dest
    PATCOPY = 0x00F00021, // dest = pattern
    PATPAINT = 0x00FB0A09, // dest = DPSnoo
    PATINVERT = 0x005A0049, // dest = pattern XOR dest
    DSTINVERT = 0x00550009, // dest = (NOT dest)
    BLACKNESS = 0x00000042, // dest = BLACK
    WHITENESS = 0x00FF0062, // dest = WHITE
    };

    /// <summary>
    /// Enumeration to be used for those Win32 function
    /// that return BOOL
    /// </summary>
    public enum Bool
    {
    False = 0,
    True
    };

    /// <summary>
    /// Sets the background color.
    /// </summary>
    /// <param name="hdc">The HDC.</param>
    /// <param name="crColor">Color of the cr.</param>
    /// <returns></returns>
    [DllImport("gdi32.dll")]
    public static extern int SetBkColor(IntPtr hdc, int crColor);

    /// <summary>
    /// CreateCompatibleDC
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern IntPtr CreateCompatibleDC(IntPtr hDC);

    /// <summary>
    /// DeleteDC
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool DeleteDC(IntPtr hdc);

    /// <summary>
    /// SelectObject
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true)]
    public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

    /// <summary>
    /// DeleteObject
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool DeleteObject(IntPtr hObject);

    /// <summary>
    /// CreateCompatibleBitmap
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern IntPtr CreateCompatibleBitmap(IntPtr hObject, int width, int height);

    /// <summary>
    /// BitBlt
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

    /// <summary>
    /// StretchBlt
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool StretchBlt(IntPtr hObject, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hObjSource, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, TernaryRasterOperations dwRop);

    /// <summary>
    /// SetStretchBltMode
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool SetStretchBltMode(IntPtr hObject, int nStretchMode);
    }





    share|improve this answer























    • GetHbitmap creates a copy of the bitmap data. This may be an issue when using large bitmaps like 10k x 10k RGB, which are around 400MB large: There will be the original Bitmap object of this size and then another "GDI bitmap" of the same size. This will almost never work in a 32 bit process, 64bit is required then: stackoverflow.com/a/11559001
      – Tobias Knauss
      Nov 9 at 16:08
















    1














    I advice you to use Control.CreateGraphics() method at Form instance, and write on a Form directly, because PaintBox control is quite slow.



    Try using my helper function, this will allow you to paste a portion of your bitmap using StretchBlt (stretching) or BitBlt (no stretching) using Win32 Interop:



    Sample usage:



    Graphics graphics = ...;
    graphics.GdiDrawImage
    (
    image,
    new Rectangle(
    (int)rectangle.Left,
    (int)rectangle.Top,
    (int)rectangle.Width,
    (int)rectangle.Height
    ),
    0, 0, image.Width, image.Height
    );


    Source code:



    public static class GraphicsHelper
    {
    public static void GdiDrawImage(this Graphics graphics, Bitmap image, Rectangle rectangleDst, int nXSrc, int nYSrc, int nWidth, int nHeight)
    {
    IntPtr hdc = graphics.GetHdc();
    IntPtr memdc = GdiInterop.CreateCompatibleDC(hdc);
    IntPtr bmp = image.GetHbitmap();
    GdiInterop.SelectObject(memdc, bmp);
    GdiInterop.SetStretchBltMode(hdc, 0x04);
    GdiInterop.StretchBlt(hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, nWidth, nHeight, GdiInterop.TernaryRasterOperations.SRCCOPY);
    //GdiInterop.BitBlt(..) put it here, if you did not mention stretching the source image
    GdiInterop.DeleteObject(bmp);
    GdiInterop.DeleteDC(memdc);
    graphics.ReleaseHdc(hdc);
    }
    }

    public class GdiInterop
    {
    /// <summary>
    /// Enumeration for the raster operations used in BitBlt.
    /// In C++ these are actually #define. But to use these
    /// constants with C#, a new enumeration _type is defined.
    /// </summary>
    public enum TernaryRasterOperations
    {
    SRCCOPY = 0x00CC0020, // dest = source
    SRCPAINT = 0x00EE0086, // dest = source OR dest
    SRCAND = 0x008800C6, // dest = source AND dest
    SRCINVERT = 0x00660046, // dest = source XOR dest
    SRCERASE = 0x00440328, // dest = source AND (NOT dest)
    NOTSRCCOPY = 0x00330008, // dest = (NOT source)
    NOTSRCERASE = 0x001100A6, // dest = (NOT src) AND (NOT dest)
    MERGECOPY = 0x00C000CA, // dest = (source AND pattern)
    MERGEPAINT = 0x00BB0226, // dest = (NOT source) OR dest
    PATCOPY = 0x00F00021, // dest = pattern
    PATPAINT = 0x00FB0A09, // dest = DPSnoo
    PATINVERT = 0x005A0049, // dest = pattern XOR dest
    DSTINVERT = 0x00550009, // dest = (NOT dest)
    BLACKNESS = 0x00000042, // dest = BLACK
    WHITENESS = 0x00FF0062, // dest = WHITE
    };

    /// <summary>
    /// Enumeration to be used for those Win32 function
    /// that return BOOL
    /// </summary>
    public enum Bool
    {
    False = 0,
    True
    };

    /// <summary>
    /// Sets the background color.
    /// </summary>
    /// <param name="hdc">The HDC.</param>
    /// <param name="crColor">Color of the cr.</param>
    /// <returns></returns>
    [DllImport("gdi32.dll")]
    public static extern int SetBkColor(IntPtr hdc, int crColor);

    /// <summary>
    /// CreateCompatibleDC
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern IntPtr CreateCompatibleDC(IntPtr hDC);

    /// <summary>
    /// DeleteDC
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool DeleteDC(IntPtr hdc);

    /// <summary>
    /// SelectObject
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true)]
    public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

    /// <summary>
    /// DeleteObject
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool DeleteObject(IntPtr hObject);

    /// <summary>
    /// CreateCompatibleBitmap
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern IntPtr CreateCompatibleBitmap(IntPtr hObject, int width, int height);

    /// <summary>
    /// BitBlt
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

    /// <summary>
    /// StretchBlt
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool StretchBlt(IntPtr hObject, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hObjSource, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, TernaryRasterOperations dwRop);

    /// <summary>
    /// SetStretchBltMode
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool SetStretchBltMode(IntPtr hObject, int nStretchMode);
    }





    share|improve this answer























    • GetHbitmap creates a copy of the bitmap data. This may be an issue when using large bitmaps like 10k x 10k RGB, which are around 400MB large: There will be the original Bitmap object of this size and then another "GDI bitmap" of the same size. This will almost never work in a 32 bit process, 64bit is required then: stackoverflow.com/a/11559001
      – Tobias Knauss
      Nov 9 at 16:08














    1












    1








    1






    I advice you to use Control.CreateGraphics() method at Form instance, and write on a Form directly, because PaintBox control is quite slow.



    Try using my helper function, this will allow you to paste a portion of your bitmap using StretchBlt (stretching) or BitBlt (no stretching) using Win32 Interop:



    Sample usage:



    Graphics graphics = ...;
    graphics.GdiDrawImage
    (
    image,
    new Rectangle(
    (int)rectangle.Left,
    (int)rectangle.Top,
    (int)rectangle.Width,
    (int)rectangle.Height
    ),
    0, 0, image.Width, image.Height
    );


    Source code:



    public static class GraphicsHelper
    {
    public static void GdiDrawImage(this Graphics graphics, Bitmap image, Rectangle rectangleDst, int nXSrc, int nYSrc, int nWidth, int nHeight)
    {
    IntPtr hdc = graphics.GetHdc();
    IntPtr memdc = GdiInterop.CreateCompatibleDC(hdc);
    IntPtr bmp = image.GetHbitmap();
    GdiInterop.SelectObject(memdc, bmp);
    GdiInterop.SetStretchBltMode(hdc, 0x04);
    GdiInterop.StretchBlt(hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, nWidth, nHeight, GdiInterop.TernaryRasterOperations.SRCCOPY);
    //GdiInterop.BitBlt(..) put it here, if you did not mention stretching the source image
    GdiInterop.DeleteObject(bmp);
    GdiInterop.DeleteDC(memdc);
    graphics.ReleaseHdc(hdc);
    }
    }

    public class GdiInterop
    {
    /// <summary>
    /// Enumeration for the raster operations used in BitBlt.
    /// In C++ these are actually #define. But to use these
    /// constants with C#, a new enumeration _type is defined.
    /// </summary>
    public enum TernaryRasterOperations
    {
    SRCCOPY = 0x00CC0020, // dest = source
    SRCPAINT = 0x00EE0086, // dest = source OR dest
    SRCAND = 0x008800C6, // dest = source AND dest
    SRCINVERT = 0x00660046, // dest = source XOR dest
    SRCERASE = 0x00440328, // dest = source AND (NOT dest)
    NOTSRCCOPY = 0x00330008, // dest = (NOT source)
    NOTSRCERASE = 0x001100A6, // dest = (NOT src) AND (NOT dest)
    MERGECOPY = 0x00C000CA, // dest = (source AND pattern)
    MERGEPAINT = 0x00BB0226, // dest = (NOT source) OR dest
    PATCOPY = 0x00F00021, // dest = pattern
    PATPAINT = 0x00FB0A09, // dest = DPSnoo
    PATINVERT = 0x005A0049, // dest = pattern XOR dest
    DSTINVERT = 0x00550009, // dest = (NOT dest)
    BLACKNESS = 0x00000042, // dest = BLACK
    WHITENESS = 0x00FF0062, // dest = WHITE
    };

    /// <summary>
    /// Enumeration to be used for those Win32 function
    /// that return BOOL
    /// </summary>
    public enum Bool
    {
    False = 0,
    True
    };

    /// <summary>
    /// Sets the background color.
    /// </summary>
    /// <param name="hdc">The HDC.</param>
    /// <param name="crColor">Color of the cr.</param>
    /// <returns></returns>
    [DllImport("gdi32.dll")]
    public static extern int SetBkColor(IntPtr hdc, int crColor);

    /// <summary>
    /// CreateCompatibleDC
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern IntPtr CreateCompatibleDC(IntPtr hDC);

    /// <summary>
    /// DeleteDC
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool DeleteDC(IntPtr hdc);

    /// <summary>
    /// SelectObject
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true)]
    public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

    /// <summary>
    /// DeleteObject
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool DeleteObject(IntPtr hObject);

    /// <summary>
    /// CreateCompatibleBitmap
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern IntPtr CreateCompatibleBitmap(IntPtr hObject, int width, int height);

    /// <summary>
    /// BitBlt
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

    /// <summary>
    /// StretchBlt
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool StretchBlt(IntPtr hObject, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hObjSource, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, TernaryRasterOperations dwRop);

    /// <summary>
    /// SetStretchBltMode
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool SetStretchBltMode(IntPtr hObject, int nStretchMode);
    }





    share|improve this answer














    I advice you to use Control.CreateGraphics() method at Form instance, and write on a Form directly, because PaintBox control is quite slow.



    Try using my helper function, this will allow you to paste a portion of your bitmap using StretchBlt (stretching) or BitBlt (no stretching) using Win32 Interop:



    Sample usage:



    Graphics graphics = ...;
    graphics.GdiDrawImage
    (
    image,
    new Rectangle(
    (int)rectangle.Left,
    (int)rectangle.Top,
    (int)rectangle.Width,
    (int)rectangle.Height
    ),
    0, 0, image.Width, image.Height
    );


    Source code:



    public static class GraphicsHelper
    {
    public static void GdiDrawImage(this Graphics graphics, Bitmap image, Rectangle rectangleDst, int nXSrc, int nYSrc, int nWidth, int nHeight)
    {
    IntPtr hdc = graphics.GetHdc();
    IntPtr memdc = GdiInterop.CreateCompatibleDC(hdc);
    IntPtr bmp = image.GetHbitmap();
    GdiInterop.SelectObject(memdc, bmp);
    GdiInterop.SetStretchBltMode(hdc, 0x04);
    GdiInterop.StretchBlt(hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, nWidth, nHeight, GdiInterop.TernaryRasterOperations.SRCCOPY);
    //GdiInterop.BitBlt(..) put it here, if you did not mention stretching the source image
    GdiInterop.DeleteObject(bmp);
    GdiInterop.DeleteDC(memdc);
    graphics.ReleaseHdc(hdc);
    }
    }

    public class GdiInterop
    {
    /// <summary>
    /// Enumeration for the raster operations used in BitBlt.
    /// In C++ these are actually #define. But to use these
    /// constants with C#, a new enumeration _type is defined.
    /// </summary>
    public enum TernaryRasterOperations
    {
    SRCCOPY = 0x00CC0020, // dest = source
    SRCPAINT = 0x00EE0086, // dest = source OR dest
    SRCAND = 0x008800C6, // dest = source AND dest
    SRCINVERT = 0x00660046, // dest = source XOR dest
    SRCERASE = 0x00440328, // dest = source AND (NOT dest)
    NOTSRCCOPY = 0x00330008, // dest = (NOT source)
    NOTSRCERASE = 0x001100A6, // dest = (NOT src) AND (NOT dest)
    MERGECOPY = 0x00C000CA, // dest = (source AND pattern)
    MERGEPAINT = 0x00BB0226, // dest = (NOT source) OR dest
    PATCOPY = 0x00F00021, // dest = pattern
    PATPAINT = 0x00FB0A09, // dest = DPSnoo
    PATINVERT = 0x005A0049, // dest = pattern XOR dest
    DSTINVERT = 0x00550009, // dest = (NOT dest)
    BLACKNESS = 0x00000042, // dest = BLACK
    WHITENESS = 0x00FF0062, // dest = WHITE
    };

    /// <summary>
    /// Enumeration to be used for those Win32 function
    /// that return BOOL
    /// </summary>
    public enum Bool
    {
    False = 0,
    True
    };

    /// <summary>
    /// Sets the background color.
    /// </summary>
    /// <param name="hdc">The HDC.</param>
    /// <param name="crColor">Color of the cr.</param>
    /// <returns></returns>
    [DllImport("gdi32.dll")]
    public static extern int SetBkColor(IntPtr hdc, int crColor);

    /// <summary>
    /// CreateCompatibleDC
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern IntPtr CreateCompatibleDC(IntPtr hDC);

    /// <summary>
    /// DeleteDC
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool DeleteDC(IntPtr hdc);

    /// <summary>
    /// SelectObject
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true)]
    public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

    /// <summary>
    /// DeleteObject
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool DeleteObject(IntPtr hObject);

    /// <summary>
    /// CreateCompatibleBitmap
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern IntPtr CreateCompatibleBitmap(IntPtr hObject, int width, int height);

    /// <summary>
    /// BitBlt
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

    /// <summary>
    /// StretchBlt
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool StretchBlt(IntPtr hObject, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hObjSource, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, TernaryRasterOperations dwRop);

    /// <summary>
    /// SetStretchBltMode
    /// </summary>
    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool SetStretchBltMode(IntPtr hObject, int nStretchMode);
    }






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Sep 20 '11 at 6:46

























    answered Sep 20 '11 at 6:38









    Artur Mustafin

    1,780817




    1,780817












    • GetHbitmap creates a copy of the bitmap data. This may be an issue when using large bitmaps like 10k x 10k RGB, which are around 400MB large: There will be the original Bitmap object of this size and then another "GDI bitmap" of the same size. This will almost never work in a 32 bit process, 64bit is required then: stackoverflow.com/a/11559001
      – Tobias Knauss
      Nov 9 at 16:08


















    • GetHbitmap creates a copy of the bitmap data. This may be an issue when using large bitmaps like 10k x 10k RGB, which are around 400MB large: There will be the original Bitmap object of this size and then another "GDI bitmap" of the same size. This will almost never work in a 32 bit process, 64bit is required then: stackoverflow.com/a/11559001
      – Tobias Knauss
      Nov 9 at 16:08
















    GetHbitmap creates a copy of the bitmap data. This may be an issue when using large bitmaps like 10k x 10k RGB, which are around 400MB large: There will be the original Bitmap object of this size and then another "GDI bitmap" of the same size. This will almost never work in a 32 bit process, 64bit is required then: stackoverflow.com/a/11559001
    – Tobias Knauss
    Nov 9 at 16:08




    GetHbitmap creates a copy of the bitmap data. This may be an issue when using large bitmaps like 10k x 10k RGB, which are around 400MB large: There will be the original Bitmap object of this size and then another "GDI bitmap" of the same size. This will almost never work in a 32 bit process, 64bit is required then: stackoverflow.com/a/11559001
    – Tobias Knauss
    Nov 9 at 16:08













    0














    Notice: This is no full answer to the question, but I want to provide some useful information to the existing answer.



    In contrast to the answer of Artur Mustafin, I suggest not to use the Windows GDI directly, but to use the .net methods of the Graphics class. In my tests they have performed a lot better than the GDI functions.



    The GDI code is taken from the answer of Artur Mustafin.

    The test was displaying an image of 1Mpix (1k x 1k) Bitmap or 100Mpix (10k x 10k) Bitmap in 1k x 1k Picturebox by drawing in the Paint event.

    The tests were done in Visual Studio 2015.3 on Windows 7 Pro x64 SP1, Debug mode, on an Intel Core i7-3630QM CPU @ 2.4 GHz, 16 GB RAM.



    Results:



    1000x Graphics.DrawImage() unscaled       of 100M Bitmap:   36.8s (x86),  24.2s (x64).
    1000x Graphics.DrawImage() unscaled of 1M Bitmap: 5.2s (x86), 3.8s (x64).
    100x Graphics.DrawImage() scaled of 100M Bitmap: 62.8s (x86), 39.0s (x64).
    1000x Graphics.DrawImage() scaled of 1M Bitmap: 5.2s (x86), 3.8s (x64).
    100x GdiDrawImage() StretchBlockTransfer of 100M Bitmap: OutOfMem@x86, 88.5s (x64).
    1000x GdiDrawImage() StretchBlockTransfer of 1M Bitmap: 12.9s (x86), 11.5s (x64).
    100x GdiDrawImage() BitBlockTransfer of 100M Bitmap: OutOfMem@x86, 49.7s (x64).
    1000x GdiDrawImage() BitBlockTransfer of 1M Bitmap: 7.2s (x86), 5.8s (x64).


    Test code:



    public partial class FormPictureboxPaint : Form
    {
    private Bitmap m_oBitmap;

    public FormPictureboxPaint ()
    {
    InitializeComponent ();

    string sFile = Application.StartupPath + @"......bitmap.png"; // The bitmap file contains an image with 10k x 10k pixels.
    m_oBitmap = new Bitmap (sFile);

    if (false) // CHANGE TO TRUE IF TESTING WITH 1k x 1k BITMAPS
    {
    var oBitmap = new Bitmap (m_oBitmap, new Size (1000, 1000));

    m_oBitmap.Dispose ();
    m_oBitmap = null;
    GC.Collect ();
    GC.WaitForFullGCComplete ();
    GC.WaitForPendingFinalizers ();

    m_oBitmap = oBitmap;
    }
    }

    private void pictureBox1_Paint (object sender, PaintEventArgs e)
    {
    var oGraphics = e.Graphics;
    DateTime dtNow = DateTime.Now;

    // UNCOMMENT THE FOLLOWING LINES FOR TESTS WITH DrawImage
    // COMMENT THE FOLLOWING LINES FOR TESTS WITH GDI
    //for (int ixCnt = 0; ixCnt < 1000; ixCnt++)
    // PictureboxPaint01 (oGraphics);

    // COMMENT THE FOLLOWING LINES FOR TESTS WITH DrawImage
    // UNCOMMENT THE FOLLOWING LINES FOR TESTS WITH GDI
    for (int ixCnt = 0; ixCnt < 100; ixCnt++)
    PictureboxPaint02 (oGraphics);

    TimeSpan ts = (DateTime.Now - dtNow);
    }

    private void PictureboxPaint01 (Graphics i_oGraphics)
    {
    //_oGraphics.DrawImage (m_oBitmap, new Point ());
    i_oGraphics.DrawImage (m_oBitmap, new Rectangle (0, 0, 1000, 1000));
    }

    private void PictureboxPaint02 (Graphics i_oGraphics)
    {
    // from https://stackoverflow.com/a/7481071
    i_oGraphics.GdiDrawImage
    (
    m_oBitmap,
    new Rectangle (
    (int)pictureBox1.Left,
    (int)pictureBox1.Top,
    (int)pictureBox1.Width,
    (int)pictureBox1.Height
    ),
    0, 0, m_oBitmap.Width, m_oBitmap.Height
    );
    }
    }

    public static class GraphicsHelper
    {
    public static void GdiDrawImage (this Graphics graphics, Bitmap image, Rectangle rectangleDst, int nXSrc, int nYSrc, int nWidth, int nHeight)
    {
    IntPtr hdc = graphics.GetHdc ();
    IntPtr memdc = GdiInterop.CreateCompatibleDC (hdc);
    IntPtr bmp = image.GetHbitmap ();
    GdiInterop.SelectObject (memdc, bmp);
    GdiInterop.SetStretchBltMode (hdc, 0x04);
    GdiInterop.StretchBlt (hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, nWidth, nHeight, GdiInterop.TernaryRasterOperations.SRCCOPY);
    //GdiInterop.BitBlt (hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, GdiInterop.TernaryRasterOperations.SRCCOPY); //put it here, if you did not mention stretching the source image
    GdiInterop.DeleteObject (bmp);
    GdiInterop.DeleteDC (memdc);
    graphics.ReleaseHdc (hdc);
    }
    }

    public class GdiInterop
    {
    public enum TernaryRasterOperations
    {
    SRCCOPY = 0x00CC0020, // dest = source
    };

    public enum Bool
    {
    False = 0,
    True
    };

    [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern IntPtr CreateCompatibleDC (IntPtr hDC);

    [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool DeleteDC (IntPtr hdc);

    [DllImport ("gdi32.dll", ExactSpelling = true)]
    public static extern IntPtr SelectObject (IntPtr hDC, IntPtr hObject);

    [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool DeleteObject (IntPtr hObject);

    [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool BitBlt (IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

    [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool StretchBlt (IntPtr hObject, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hObjSource, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, TernaryRasterOperations dwRop);

    [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern Bool SetStretchBltMode (IntPtr hObject, int nStretchMode);
    }





    share|improve this answer


























      0














      Notice: This is no full answer to the question, but I want to provide some useful information to the existing answer.



      In contrast to the answer of Artur Mustafin, I suggest not to use the Windows GDI directly, but to use the .net methods of the Graphics class. In my tests they have performed a lot better than the GDI functions.



      The GDI code is taken from the answer of Artur Mustafin.

      The test was displaying an image of 1Mpix (1k x 1k) Bitmap or 100Mpix (10k x 10k) Bitmap in 1k x 1k Picturebox by drawing in the Paint event.

      The tests were done in Visual Studio 2015.3 on Windows 7 Pro x64 SP1, Debug mode, on an Intel Core i7-3630QM CPU @ 2.4 GHz, 16 GB RAM.



      Results:



      1000x Graphics.DrawImage() unscaled       of 100M Bitmap:   36.8s (x86),  24.2s (x64).
      1000x Graphics.DrawImage() unscaled of 1M Bitmap: 5.2s (x86), 3.8s (x64).
      100x Graphics.DrawImage() scaled of 100M Bitmap: 62.8s (x86), 39.0s (x64).
      1000x Graphics.DrawImage() scaled of 1M Bitmap: 5.2s (x86), 3.8s (x64).
      100x GdiDrawImage() StretchBlockTransfer of 100M Bitmap: OutOfMem@x86, 88.5s (x64).
      1000x GdiDrawImage() StretchBlockTransfer of 1M Bitmap: 12.9s (x86), 11.5s (x64).
      100x GdiDrawImage() BitBlockTransfer of 100M Bitmap: OutOfMem@x86, 49.7s (x64).
      1000x GdiDrawImage() BitBlockTransfer of 1M Bitmap: 7.2s (x86), 5.8s (x64).


      Test code:



      public partial class FormPictureboxPaint : Form
      {
      private Bitmap m_oBitmap;

      public FormPictureboxPaint ()
      {
      InitializeComponent ();

      string sFile = Application.StartupPath + @"......bitmap.png"; // The bitmap file contains an image with 10k x 10k pixels.
      m_oBitmap = new Bitmap (sFile);

      if (false) // CHANGE TO TRUE IF TESTING WITH 1k x 1k BITMAPS
      {
      var oBitmap = new Bitmap (m_oBitmap, new Size (1000, 1000));

      m_oBitmap.Dispose ();
      m_oBitmap = null;
      GC.Collect ();
      GC.WaitForFullGCComplete ();
      GC.WaitForPendingFinalizers ();

      m_oBitmap = oBitmap;
      }
      }

      private void pictureBox1_Paint (object sender, PaintEventArgs e)
      {
      var oGraphics = e.Graphics;
      DateTime dtNow = DateTime.Now;

      // UNCOMMENT THE FOLLOWING LINES FOR TESTS WITH DrawImage
      // COMMENT THE FOLLOWING LINES FOR TESTS WITH GDI
      //for (int ixCnt = 0; ixCnt < 1000; ixCnt++)
      // PictureboxPaint01 (oGraphics);

      // COMMENT THE FOLLOWING LINES FOR TESTS WITH DrawImage
      // UNCOMMENT THE FOLLOWING LINES FOR TESTS WITH GDI
      for (int ixCnt = 0; ixCnt < 100; ixCnt++)
      PictureboxPaint02 (oGraphics);

      TimeSpan ts = (DateTime.Now - dtNow);
      }

      private void PictureboxPaint01 (Graphics i_oGraphics)
      {
      //_oGraphics.DrawImage (m_oBitmap, new Point ());
      i_oGraphics.DrawImage (m_oBitmap, new Rectangle (0, 0, 1000, 1000));
      }

      private void PictureboxPaint02 (Graphics i_oGraphics)
      {
      // from https://stackoverflow.com/a/7481071
      i_oGraphics.GdiDrawImage
      (
      m_oBitmap,
      new Rectangle (
      (int)pictureBox1.Left,
      (int)pictureBox1.Top,
      (int)pictureBox1.Width,
      (int)pictureBox1.Height
      ),
      0, 0, m_oBitmap.Width, m_oBitmap.Height
      );
      }
      }

      public static class GraphicsHelper
      {
      public static void GdiDrawImage (this Graphics graphics, Bitmap image, Rectangle rectangleDst, int nXSrc, int nYSrc, int nWidth, int nHeight)
      {
      IntPtr hdc = graphics.GetHdc ();
      IntPtr memdc = GdiInterop.CreateCompatibleDC (hdc);
      IntPtr bmp = image.GetHbitmap ();
      GdiInterop.SelectObject (memdc, bmp);
      GdiInterop.SetStretchBltMode (hdc, 0x04);
      GdiInterop.StretchBlt (hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, nWidth, nHeight, GdiInterop.TernaryRasterOperations.SRCCOPY);
      //GdiInterop.BitBlt (hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, GdiInterop.TernaryRasterOperations.SRCCOPY); //put it here, if you did not mention stretching the source image
      GdiInterop.DeleteObject (bmp);
      GdiInterop.DeleteDC (memdc);
      graphics.ReleaseHdc (hdc);
      }
      }

      public class GdiInterop
      {
      public enum TernaryRasterOperations
      {
      SRCCOPY = 0x00CC0020, // dest = source
      };

      public enum Bool
      {
      False = 0,
      True
      };

      [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
      public static extern IntPtr CreateCompatibleDC (IntPtr hDC);

      [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
      public static extern Bool DeleteDC (IntPtr hdc);

      [DllImport ("gdi32.dll", ExactSpelling = true)]
      public static extern IntPtr SelectObject (IntPtr hDC, IntPtr hObject);

      [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
      public static extern Bool DeleteObject (IntPtr hObject);

      [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
      public static extern Bool BitBlt (IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

      [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
      public static extern Bool StretchBlt (IntPtr hObject, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hObjSource, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, TernaryRasterOperations dwRop);

      [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
      public static extern Bool SetStretchBltMode (IntPtr hObject, int nStretchMode);
      }





      share|improve this answer
























        0












        0








        0






        Notice: This is no full answer to the question, but I want to provide some useful information to the existing answer.



        In contrast to the answer of Artur Mustafin, I suggest not to use the Windows GDI directly, but to use the .net methods of the Graphics class. In my tests they have performed a lot better than the GDI functions.



        The GDI code is taken from the answer of Artur Mustafin.

        The test was displaying an image of 1Mpix (1k x 1k) Bitmap or 100Mpix (10k x 10k) Bitmap in 1k x 1k Picturebox by drawing in the Paint event.

        The tests were done in Visual Studio 2015.3 on Windows 7 Pro x64 SP1, Debug mode, on an Intel Core i7-3630QM CPU @ 2.4 GHz, 16 GB RAM.



        Results:



        1000x Graphics.DrawImage() unscaled       of 100M Bitmap:   36.8s (x86),  24.2s (x64).
        1000x Graphics.DrawImage() unscaled of 1M Bitmap: 5.2s (x86), 3.8s (x64).
        100x Graphics.DrawImage() scaled of 100M Bitmap: 62.8s (x86), 39.0s (x64).
        1000x Graphics.DrawImage() scaled of 1M Bitmap: 5.2s (x86), 3.8s (x64).
        100x GdiDrawImage() StretchBlockTransfer of 100M Bitmap: OutOfMem@x86, 88.5s (x64).
        1000x GdiDrawImage() StretchBlockTransfer of 1M Bitmap: 12.9s (x86), 11.5s (x64).
        100x GdiDrawImage() BitBlockTransfer of 100M Bitmap: OutOfMem@x86, 49.7s (x64).
        1000x GdiDrawImage() BitBlockTransfer of 1M Bitmap: 7.2s (x86), 5.8s (x64).


        Test code:



        public partial class FormPictureboxPaint : Form
        {
        private Bitmap m_oBitmap;

        public FormPictureboxPaint ()
        {
        InitializeComponent ();

        string sFile = Application.StartupPath + @"......bitmap.png"; // The bitmap file contains an image with 10k x 10k pixels.
        m_oBitmap = new Bitmap (sFile);

        if (false) // CHANGE TO TRUE IF TESTING WITH 1k x 1k BITMAPS
        {
        var oBitmap = new Bitmap (m_oBitmap, new Size (1000, 1000));

        m_oBitmap.Dispose ();
        m_oBitmap = null;
        GC.Collect ();
        GC.WaitForFullGCComplete ();
        GC.WaitForPendingFinalizers ();

        m_oBitmap = oBitmap;
        }
        }

        private void pictureBox1_Paint (object sender, PaintEventArgs e)
        {
        var oGraphics = e.Graphics;
        DateTime dtNow = DateTime.Now;

        // UNCOMMENT THE FOLLOWING LINES FOR TESTS WITH DrawImage
        // COMMENT THE FOLLOWING LINES FOR TESTS WITH GDI
        //for (int ixCnt = 0; ixCnt < 1000; ixCnt++)
        // PictureboxPaint01 (oGraphics);

        // COMMENT THE FOLLOWING LINES FOR TESTS WITH DrawImage
        // UNCOMMENT THE FOLLOWING LINES FOR TESTS WITH GDI
        for (int ixCnt = 0; ixCnt < 100; ixCnt++)
        PictureboxPaint02 (oGraphics);

        TimeSpan ts = (DateTime.Now - dtNow);
        }

        private void PictureboxPaint01 (Graphics i_oGraphics)
        {
        //_oGraphics.DrawImage (m_oBitmap, new Point ());
        i_oGraphics.DrawImage (m_oBitmap, new Rectangle (0, 0, 1000, 1000));
        }

        private void PictureboxPaint02 (Graphics i_oGraphics)
        {
        // from https://stackoverflow.com/a/7481071
        i_oGraphics.GdiDrawImage
        (
        m_oBitmap,
        new Rectangle (
        (int)pictureBox1.Left,
        (int)pictureBox1.Top,
        (int)pictureBox1.Width,
        (int)pictureBox1.Height
        ),
        0, 0, m_oBitmap.Width, m_oBitmap.Height
        );
        }
        }

        public static class GraphicsHelper
        {
        public static void GdiDrawImage (this Graphics graphics, Bitmap image, Rectangle rectangleDst, int nXSrc, int nYSrc, int nWidth, int nHeight)
        {
        IntPtr hdc = graphics.GetHdc ();
        IntPtr memdc = GdiInterop.CreateCompatibleDC (hdc);
        IntPtr bmp = image.GetHbitmap ();
        GdiInterop.SelectObject (memdc, bmp);
        GdiInterop.SetStretchBltMode (hdc, 0x04);
        GdiInterop.StretchBlt (hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, nWidth, nHeight, GdiInterop.TernaryRasterOperations.SRCCOPY);
        //GdiInterop.BitBlt (hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, GdiInterop.TernaryRasterOperations.SRCCOPY); //put it here, if you did not mention stretching the source image
        GdiInterop.DeleteObject (bmp);
        GdiInterop.DeleteDC (memdc);
        graphics.ReleaseHdc (hdc);
        }
        }

        public class GdiInterop
        {
        public enum TernaryRasterOperations
        {
        SRCCOPY = 0x00CC0020, // dest = source
        };

        public enum Bool
        {
        False = 0,
        True
        };

        [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern IntPtr CreateCompatibleDC (IntPtr hDC);

        [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern Bool DeleteDC (IntPtr hdc);

        [DllImport ("gdi32.dll", ExactSpelling = true)]
        public static extern IntPtr SelectObject (IntPtr hDC, IntPtr hObject);

        [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern Bool DeleteObject (IntPtr hObject);

        [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern Bool BitBlt (IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

        [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern Bool StretchBlt (IntPtr hObject, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hObjSource, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, TernaryRasterOperations dwRop);

        [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern Bool SetStretchBltMode (IntPtr hObject, int nStretchMode);
        }





        share|improve this answer












        Notice: This is no full answer to the question, but I want to provide some useful information to the existing answer.



        In contrast to the answer of Artur Mustafin, I suggest not to use the Windows GDI directly, but to use the .net methods of the Graphics class. In my tests they have performed a lot better than the GDI functions.



        The GDI code is taken from the answer of Artur Mustafin.

        The test was displaying an image of 1Mpix (1k x 1k) Bitmap or 100Mpix (10k x 10k) Bitmap in 1k x 1k Picturebox by drawing in the Paint event.

        The tests were done in Visual Studio 2015.3 on Windows 7 Pro x64 SP1, Debug mode, on an Intel Core i7-3630QM CPU @ 2.4 GHz, 16 GB RAM.



        Results:



        1000x Graphics.DrawImage() unscaled       of 100M Bitmap:   36.8s (x86),  24.2s (x64).
        1000x Graphics.DrawImage() unscaled of 1M Bitmap: 5.2s (x86), 3.8s (x64).
        100x Graphics.DrawImage() scaled of 100M Bitmap: 62.8s (x86), 39.0s (x64).
        1000x Graphics.DrawImage() scaled of 1M Bitmap: 5.2s (x86), 3.8s (x64).
        100x GdiDrawImage() StretchBlockTransfer of 100M Bitmap: OutOfMem@x86, 88.5s (x64).
        1000x GdiDrawImage() StretchBlockTransfer of 1M Bitmap: 12.9s (x86), 11.5s (x64).
        100x GdiDrawImage() BitBlockTransfer of 100M Bitmap: OutOfMem@x86, 49.7s (x64).
        1000x GdiDrawImage() BitBlockTransfer of 1M Bitmap: 7.2s (x86), 5.8s (x64).


        Test code:



        public partial class FormPictureboxPaint : Form
        {
        private Bitmap m_oBitmap;

        public FormPictureboxPaint ()
        {
        InitializeComponent ();

        string sFile = Application.StartupPath + @"......bitmap.png"; // The bitmap file contains an image with 10k x 10k pixels.
        m_oBitmap = new Bitmap (sFile);

        if (false) // CHANGE TO TRUE IF TESTING WITH 1k x 1k BITMAPS
        {
        var oBitmap = new Bitmap (m_oBitmap, new Size (1000, 1000));

        m_oBitmap.Dispose ();
        m_oBitmap = null;
        GC.Collect ();
        GC.WaitForFullGCComplete ();
        GC.WaitForPendingFinalizers ();

        m_oBitmap = oBitmap;
        }
        }

        private void pictureBox1_Paint (object sender, PaintEventArgs e)
        {
        var oGraphics = e.Graphics;
        DateTime dtNow = DateTime.Now;

        // UNCOMMENT THE FOLLOWING LINES FOR TESTS WITH DrawImage
        // COMMENT THE FOLLOWING LINES FOR TESTS WITH GDI
        //for (int ixCnt = 0; ixCnt < 1000; ixCnt++)
        // PictureboxPaint01 (oGraphics);

        // COMMENT THE FOLLOWING LINES FOR TESTS WITH DrawImage
        // UNCOMMENT THE FOLLOWING LINES FOR TESTS WITH GDI
        for (int ixCnt = 0; ixCnt < 100; ixCnt++)
        PictureboxPaint02 (oGraphics);

        TimeSpan ts = (DateTime.Now - dtNow);
        }

        private void PictureboxPaint01 (Graphics i_oGraphics)
        {
        //_oGraphics.DrawImage (m_oBitmap, new Point ());
        i_oGraphics.DrawImage (m_oBitmap, new Rectangle (0, 0, 1000, 1000));
        }

        private void PictureboxPaint02 (Graphics i_oGraphics)
        {
        // from https://stackoverflow.com/a/7481071
        i_oGraphics.GdiDrawImage
        (
        m_oBitmap,
        new Rectangle (
        (int)pictureBox1.Left,
        (int)pictureBox1.Top,
        (int)pictureBox1.Width,
        (int)pictureBox1.Height
        ),
        0, 0, m_oBitmap.Width, m_oBitmap.Height
        );
        }
        }

        public static class GraphicsHelper
        {
        public static void GdiDrawImage (this Graphics graphics, Bitmap image, Rectangle rectangleDst, int nXSrc, int nYSrc, int nWidth, int nHeight)
        {
        IntPtr hdc = graphics.GetHdc ();
        IntPtr memdc = GdiInterop.CreateCompatibleDC (hdc);
        IntPtr bmp = image.GetHbitmap ();
        GdiInterop.SelectObject (memdc, bmp);
        GdiInterop.SetStretchBltMode (hdc, 0x04);
        GdiInterop.StretchBlt (hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, nWidth, nHeight, GdiInterop.TernaryRasterOperations.SRCCOPY);
        //GdiInterop.BitBlt (hdc, rectangleDst.Left, rectangleDst.Top, rectangleDst.Width, rectangleDst.Height, memdc, nXSrc, nYSrc, GdiInterop.TernaryRasterOperations.SRCCOPY); //put it here, if you did not mention stretching the source image
        GdiInterop.DeleteObject (bmp);
        GdiInterop.DeleteDC (memdc);
        graphics.ReleaseHdc (hdc);
        }
        }

        public class GdiInterop
        {
        public enum TernaryRasterOperations
        {
        SRCCOPY = 0x00CC0020, // dest = source
        };

        public enum Bool
        {
        False = 0,
        True
        };

        [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern IntPtr CreateCompatibleDC (IntPtr hDC);

        [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern Bool DeleteDC (IntPtr hdc);

        [DllImport ("gdi32.dll", ExactSpelling = true)]
        public static extern IntPtr SelectObject (IntPtr hDC, IntPtr hObject);

        [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern Bool DeleteObject (IntPtr hObject);

        [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern Bool BitBlt (IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

        [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern Bool StretchBlt (IntPtr hObject, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hObjSource, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, TernaryRasterOperations dwRop);

        [DllImport ("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern Bool SetStretchBltMode (IntPtr hObject, int nStretchMode);
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 13 at 9:02









        Tobias Knauss

        1,95211230




        1,95211230






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f7481004%2fc-sharp-move-bitmap-in-picturebox%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            How to pass form data using jquery Ajax to insert data in database?

            National Museum of Racing and Hall of Fame

            Guess what letter conforming each word