Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用intptr中的可写位图创建位图时使用WritePixels。_C#_Image Processing_Bitmap_Scanning - Fatal编程技术网

C# 使用intptr中的可写位图创建位图时使用WritePixels。

C# 使用intptr中的可写位图创建位图时使用WritePixels。,c#,image-processing,bitmap,scanning,C#,Image Processing,Bitmap,Scanning,我目前正在尝试使用writeablebitmap对图像进行IntPtr扫描,并将每个图像转换为位图。我想使用writeablebitmap,因为我对标准gdi有问题 WriteableBitmap上有一个方法称为WritePixels 我不确定我为缓冲区和步幅设置了什么,我找到的每个示例都显示步幅为0,尽管这会抛出一个错误。当我将步幅设置为5时,图像显示为黑色。我知道这可能不是最有效的代码,但任何帮助都将不胜感激 //create bitmap header bmi = new BITMAP

我目前正在尝试使用writeablebitmap对图像进行
IntPtr
扫描,并将每个图像转换为
位图
。我想使用writeablebitmap,因为我对标准gdi有问题

WriteableBitmap
上有一个方法称为
WritePixels

我不确定我为缓冲区和步幅设置了什么,我找到的每个示例都显示步幅为0,尽管这会抛出一个错误。当我将步幅设置为5时,图像显示为黑色。我知道这可能不是最有效的代码,但任何帮助都将不胜感激

//create bitmap header
bmi = new BITMAPINFOHEADER();

//create initial rectangle
Int32Rect rect = new Int32Rect(0, 0, 0, 0);

//create duplicate intptr to use while in global lock
dibhand = dibhandp;
bmpptr = GlobalLock(dibhand);

//get the pixel sizes
pixptr = GetPixelInfo(bmpptr);

//create writeable bitmap
var wbitm = new WriteableBitmap(bmprect.Width, bmprect.Height, 96.0, 96.0, System.Windows.Media.PixelFormats.Bgr32, null);

//draw the image
wbitm.WritePixels(rect, dibhandp, 10, 0);

//convert the writeable bitmap to bitmap
var stream = new MemoryStream();

var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(wbitm));
encoder.Save(stream);

byte[] buffer = stream.GetBuffer();
var bitmap = new System.Drawing.Bitmap(new MemoryStream(buffer));

GlobalUnlock(dibhand);
GlobalFree(dibhand);
GlobalFree(dibhandp);
GlobalFree(bmpptr);
dibhand = IntPtr.Zero;

return bitmap;

在C#中处理位图的一个有效方法是在不安全模式下临时通过(我知道我没有准确回答这个问题,但我认为OP没有使用位图,因此这可能是一个解决方案)。您只需锁定位即可:

unsafe private void GaussianFilter()
{
    // Working images
    using (Bitmap newImage = new Bitmap(width, height))
    {
        // Lock bits for performance reason
        BitmapData newImageData = newImage.LockBits(new Rectangle(0, 0, newImage.Width,
            newImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

        byte* pointer = (byte*)newImageData.Scan0;
        int offset = newImageData.Stride - newImageData.Width * 4;

        // Compute gaussian filter on temp image
        for (int j = 0; j < InputData.Height - 1; ++j)
        {
            for (int 0 = 1; i < InputData.Width - 1; ++i)
            {
                // You browse 4 bytes per 4 bytes
                // The 4 bytes are: B G R A
                byte blue = pointer[0];
                byte green = pointer[1];
                byte red = pointer[2];
                byte alpha = pointer[3];

                // Your business here by setting pointer[i] = ...
                // If you don't use alpha don't forget to set it to 255 else your whole image will be black !!

                // Go to next pixels
                pointer += 4;
            }
            // Go to next line: do not forget pixel at last and first column
            pointer += offset;
        }


        // Unlock image
        newImage.UnlockBits(newImageData);
        newImage.Save("D:\temp\OCR_gray_gaussian.tif");
    }
}
不安全的私有无效GaussianFilter()
{
//工作图像
使用(位图newImage=新位图(宽度、高度))
{
//出于性能原因锁定位
BitmapData newImageData=newImage.LockBits(新矩形(0,0,newImage.Width,
newImage.Height)、ImageLockMode.ReadOnly、PixelFormat.Format32bppArgb);
字节*指针=(字节*)newImageData.Scan0;
int offset=newImageData.Stride-newImageData.Width*4;
//temp图像的高斯滤波计算
对于(int j=0;j
这比设置像素(i,j)要有效得多,您只需小心指针限制(完成后不要忘记解锁数据)

现在回答你关于步幅的问题:步幅是一行的长度(以字节为单位),是4的倍数。在我的示例中,我使用的格式是
Format32bppArgb
,它每像素使用4个字节(R、G、B和alpha),因此
newImageData.Stride
newImageData.Width*4
总是相同的。我在循环中使用偏移量只是为了显示需要偏移的位置

但如果您使用另一种格式,例如
Format24bppRgb
,它每像素使用3个字节(仅限R、G和B),则步幅和宽度之间可能存在偏移。对于这种格式的10*10像素图像,您将有一个10*3=30,+2的步长,以达到4的最接近倍数,即32