锁定位的图像失真 [英] Image Distortion with Lock Bits

查看:96
本文介绍了锁定位的图像失真的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用锁定位写入文件时遇到问题。我正在研究一种边缘检测软件,它对大多数图像都有奇怪的失真效果。我试图孤立这个问题,看起来很随机。它与格式无关,而是唯一可用的图像是为桌面壁纸制作的图片,我真的不知道为什么。我最近只使用lockbits切换到写入文件,所以我确定问题就在于(当我使用lockbits读取并使用set pixel写入时没有问题)。以下是该效果的屏幕截图:

I'm having a problem with writing to files using lock bits. I'm working on an edge detection software which has a strange distortion effect with most images. I've tried to isolate the problem, and it seems very random. It is not associated with format, but rather the only images that seem to work are pictures made for desktop wallpapers, and I don't really know why. I only switched to writing to files using lockbits recently, so I am sure the problem is with that (there were no problems when I was reading with lockbits and writing with set pixel). Here's a screenshot of the effect:

如您所见,边缘检测有效,但图像水平扭曲,使图像成为平行四边形。

As you can see, the edge detection works, but the image is distorted horizontally, making the image into a parallelogram.

以下是处理所有这些问题的方法的代码片段(在C#中):

Here's a code snippet of the method that handles all this (in C#):

private void analyze()
{
    //When the analyze button is pressed
    percentageInt = float.Parse(textBox1.Text);
    float scale = 1;

    if (comboBox1.SelectedItem == "Auto")
    {
        scale = pic.Width / pictureBox1.Width;
    }
    else if (comboBox1.SelectedItem == "1/2")
    {
        scale = 2;
    }
    else if (comboBox1.SelectedItem == "1/4")
    {
        scale = 4;
    }
    else if (comboBox1.SelectedItem == "Original")
    {
        scale = 1;
    }
    else
    {
        scale = pic.Width / pictureBox1.Width;
    }

    int tempWidth = 1;
    int tempHeight = 1;
    if (scale >= 1)
    {
        tempWidth = (int)Math.Floor(pic.Width / scale);
        tempHeight = (int)Math.Floor(pic.Height / scale);
    }
    else
    {
        tempWidth = pic.Width;
        tempHeight = pic.Height;
    }

    width = pic.Width;
    height = pic.Height;
    edgeData = new Boolean[pic.Width, pic.Height];

    img = (Bitmap)resizeImage(pic, new Size(tempWidth, tempHeight));
    pic2 = new Bitmap(tempWidth, tempHeight);
    Bitmap img2 = (Bitmap)pic2;
    Color[] pixels = null;

    BitmapData data = img.LockBits(new Rectangle(0, 0, img.Width, img.Height),
            ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

    int size = Math.Abs(data.Stride) * img.Height;
    Byte[] bytes = new byte[size];

    int scaledPercent = (int)(Math.Round(percentageInt * 255));
    Debug.WriteLine("percent " + scaledPercent);
    unsafe
    {
        Debug.WriteLine("Woah there, unsafe stuff");
        byte* prevLine = (byte*)data.Scan0;
        byte* currLine = prevLine + data.Stride;
        byte* nextLine = currLine + data.Stride;

        for (int y = 1; y < img.Height - 1; y++)
        {
            byte* pp = prevLine + 3;
            byte* cp = currLine + 3;
            byte* np = nextLine + 3;
            for (int x = 1; x < img.Width - 1; x++)
            {
                if (IsEdgeOptimized(pp, cp, np, scaledPercent))
                {
                    edgeData[x, y] = true;
                    //Debug.WriteLine("x " + x + "y " + y);

                    //img2.SetPixel(x, y, Color.Black);
                    //bytes[(y * img.Width + x) * 3 + 2] = 255;
                }
                else
                {
                    bytes[(y * img.Width + x) * 3] = 255;
                    bytes[(y * img.Width + x) * 3 + 1] = 255;
                    bytes[(y * img.Width + x) * 3 + 2] = 255;
                    //img2.SetPixel(x, y, Color.White);
                }
                pp += 3; cp += 3; np += 3;
            }
            prevLine = currLine;
            currLine = nextLine;
            nextLine += data.Stride;
        }
    }
    System.Runtime.InteropServices.Marshal.Copy(bytes, 0, data.Scan0, size);
    img.UnlockBits(data);
    pictureBox2.Image = img;
} // end analyze

那么是什么导致了这个问题,我该如何修复它?如果您需要更多详细信息,请随时发表评论。

So what is causing the problem, and how can I fix it? If you need more details, feel free to comment.

推荐答案

您正在使用stride x height bytes初始化字节缓冲区:

You're initializing your bytes buffer with stride x height bytes:

int size = Math.Abs(data.Stride) * img.Height;
Byte[] bytes = new byte[size];

然后在写信时使用宽度(而不是步幅):

But then using the width (instead of stride) when you write to it:

bytes[(y * img.Width + x) * 3] = 255;

这篇关于锁定位的图像失真的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆