gpt4 book ai didi

c# - 如何将现有内存缓冲区包装为 GDI 的 DC

转载 作者:太空狗 更新时间:2023-10-29 21:09:32 24 4
gpt4 key购买 nike

我有一个与我的屏幕分辨率(1280x800,每像素 24 位)相对应的内存缓冲区,其中包含我的 24bpp 屏幕内容。我想将其转换为 8-bpp(即 Windows 中的半色调调色板)。我目前这样做:1. 使用 CreateDIBSection 分配一个新的 1280x800 24-bpp 缓冲区并将其作为 DC 以及普通内存缓冲区访问2. 使用 memcpy 从我的原始缓冲区复制到步骤 1 中的这个新缓冲区3.使用BitBlt让GDI进行颜色转换

我想避免步骤 2 的额外 memcpy。为此,我可以想到两种方法:

一个。将我原来的 mem buf 包装在一个 DC 中以直接从它执行 BitBlt

编写我自己的 24-bpp 到 8-bpp 颜色转换。我找不到有关 Windows 如何实现此半色调颜色转换的任何信息。此外,即使我知道了,我也不会使用 BitBlt 可以访问的 GDI 加速功能。

那么我该怎么做 (a) 或 (b)?

谢谢!

最佳答案

好的,解决问题的两个部分。

  1. 以下代码展示了如何获取位图中的像素、更改它们并将它们放回位图中。你总是可以生成一个正确大小和格式的虚拟位图,打开它,复制你的数据,然后你有一个包含你的数据的位图对象:

    private void LockUnlockBitsExample(PaintEventArgs e)
    {

    // Create a new bitmap.
    Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg");

    // Lock the bitmap's bits.
    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
    System.Drawing.Imaging.BitmapData bmpData =
    bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
    bmp.PixelFormat);

    // Get the address of the first line.
    IntPtr ptr = bmpData.Scan0;

    // Declare an array to hold the bytes of the bitmap.
    int bytes = bmpData.Stride * bmp.Height;
    byte[] rgbValues = new byte[bytes];

    // Copy the RGB values into the array.
    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

    // Set every third value to 255. A 24bpp bitmap will look red.
    for (int counter = 2; counter < rgbValues.Length; counter += 3)
    rgbValues[counter] = 255;

    // Copy the RGB values back to the bitmap
    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);

    // Unlock the bits.
    bmp.UnlockBits(bmpData);

    // Draw the modified image.
    e.Graphics.DrawImage(bmp, 0, 150);
    }

要将内容转换为 8bpp,您需要使用 System.Drawing.Imaging.ColorMatrix 类。我手边没有正确的半色调矩阵值,但是这个示例灰度和值的调整应该让您了解效果:

Graphics g = e.Graphics;
Bitmap bmp = new Bitmap("sample.jpg");
g.FillRectangle(Brushes.White, this.ClientRectangle);

// Create a color matrix
// The value 0.6 in row 4, column 4 specifies the alpha value
float[][] matrixItems = {
new float[] {1, 0, 0, 0, 0},
new float[] {0, 1, 0, 0, 0},
new float[] {0, 0, 1, 0, 0},
new float[] {0, 0, 0, 0.6f, 0},
new float[] {0, 0, 0, 0, 1}};
ColorMatrix colorMatrix = new ColorMatrix(matrixItems);

// Create an ImageAttributes object and set its color matrix
ImageAttributes imageAtt = new ImageAttributes();
imageAtt.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

// Now draw the semitransparent bitmap image.
g.DrawImage(bmp, this.ClientRectangle, 0.0f, 0.0f, bmp.Width, bmp.Height,
GraphicsUnit.Pixel, imageAtt);

imageAtt.Dispose();

稍后我将尝试更新半色调的矩阵值,其中可能有很多 0.5 或 0.333 值!

关于c# - 如何将现有内存缓冲区包装为 GDI 的 DC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/91511/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com