سؤال

أحاول استخدام هذا الرمز لرسم ملف Bitmap مباشرة على أ PictureBox:

Bitmap bmp = (Bitmap)Bitmap.FromFile(@"C:\Users\Ken\Desktop\Load2.bmp");
Graphics grDest = Graphics.FromHwnd(pictureBox1.Handle);
Graphics grSrc = Graphics.FromImage(bmp);
IntPtr hdcDest = grDest.GetHdc();
IntPtr hdcSrc = grSrc.GetHdc();
BitBlt(hdcDest, 0, 0, pictureBox1.Width, pictureBox1.Height,
    hdcSrc, 0, 0, (uint)TernaryRasterOperations.SRCCOPY); // 0x00CC0020
grDest.ReleaseHdc(hdcDest);
grSrc.ReleaseHdc(hdcSrc);

ولكن بدلا من تقديم Bitmapمحتويات أنها ترسم فقط كتلة صلبة من الأسود تقريبا. أنا متأكد من أن المشكلة هي مع مصدر HDC ، لأنه إذا قمت بتغيير srccopy إلى البياض في الكود أعلاه ، فإنه يرسم كتلة بيضاء صلبة ، كما هو متوقع.

ملاحظة: يعمل هذا المقتطف التالي بشكل جيد ، لذلك لا حرج في صورة نقطية نفسها:

Bitmap bmp = (Bitmap)Bitmap.FromFile(@"C:\Users\Ken\Desktop\Load2.bmp");
pictureBox1.Image = bmp;
هل كانت مفيدة؟

المحلول

هذا لأن سياق الجهاز يحتوي على صورة نقطية سوداء 1 × 1 حتى SelectObject يستخدم. لاي سبب كان، Graphics.FromImage يمنحك سياقًا للجهاز متوافقًا مع صورة BITMAP ، ولكنه لا يحدد تلقائيًا الصورة النقطية في سياق الجهاز.

سيتم استخدام الرمز التالي SelectObject.

يجب عليك ، بالطبع ، استخدام المدارة Graphics.DrawImage بدلاً من BitBlt إذا كان ذلك ممكنًا ، لكنني أفترض أن لديك سبب وجيه لاستخدامه BitBlt.

private void Draw()
{
    using (Bitmap bmp = (Bitmap)Bitmap.FromFile(@"C:\Jason\forest.jpg"))
    using (Graphics grDest = Graphics.FromHwnd(pictureBox1.Handle))
    using (Graphics grSrc = Graphics.FromImage(bmp))
    {
        IntPtr hdcDest = IntPtr.Zero;
        IntPtr hdcSrc = IntPtr.Zero;
        IntPtr hBitmap = IntPtr.Zero;
        IntPtr hOldObject = IntPtr.Zero;

        try
        {
            hdcDest = grDest.GetHdc();
            hdcSrc = grSrc.GetHdc();
            hBitmap = bmp.GetHbitmap();

            hOldObject = SelectObject(hdcSrc, hBitmap);
            if (hOldObject == IntPtr.Zero)
                throw new Win32Exception();

            if (!BitBlt(hdcDest, 0, 0, pictureBox1.Width, pictureBox1.Height,
                hdcSrc, 0, 0, 0x00CC0020U))
                throw new Win32Exception();
        }
        finally
        {
            if (hOldObject != IntPtr.Zero) SelectObject(hdcSrc, hOldObject);
            if (hBitmap != IntPtr.Zero) DeleteObject(hBitmap);
            if (hdcDest != IntPtr.Zero) grDest.ReleaseHdc(hdcDest);
            if (hdcSrc != IntPtr.Zero) grSrc.ReleaseHdc(hdcSrc);
        }
    }
}

[DllImport("gdi32.dll", EntryPoint = "SelectObject")]
public static extern System.IntPtr SelectObject(
    [In()] System.IntPtr hdc,
    [In()] System.IntPtr h);

[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteObject(
    [In()] System.IntPtr ho);

[DllImport("gdi32.dll", EntryPoint = "BitBlt")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool BitBlt(
    [In()] System.IntPtr hdc, int x, int y, int cx, int cy,
    [In()] System.IntPtr hdcSrc, int x1, int y1, uint rop);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top