C#不安全代码-访问冲突-图像字节 [英] C# unsafe code - access violation - image bytes

查看:108
本文介绍了C#不安全代码-访问冲突-图像字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,所以我使用了一些调整图像对比度的代码:

Ok, so I''m using some code that adjusts an images contrast:

public static Bitmap AdjustContrast(Bitmap Image, float Value) 
        { 
            Value = (100.0f + Value) / 100.0f; 
            Value *= Value; 
            Bitmap NewBitmap = (Bitmap)Image.Clone(); 
            BitmapData data = NewBitmap.LockBits(new Rectangle(0, 0, NewBitmap.Width, NewBitmap.Height), ImageLockMode.ReadWrite, NewBitmap.PixelFormat); 
            
            unsafe 
            {
                for (int y = 0; y < NewBitmap.Height; ++y)
                {
                    byte* row = (byte*)data.Scan0 + (y * data.Stride);
                    int columnOffset = 0;

                    for (int x = 0; x < NewBitmap.Width; ++x)
                    {
                        try
                        {
                            byte B = row[columnOffset];
                            byte G = row[columnOffset + 1];
                            byte R = row[columnOffset + 2];
                            float Red = R / 255.0f;
                            float Green = G / 255.0f;
                            float Blue = B / 255.0f;
                            Red = (((Red - 0.5f) * Value) + 0.5f) * 255.0f;
                            Green = (((Green - 0.5f) * Value) + 0.5f) * 255.0f;
                            Blue = (((Blue - 0.5f) * Value) + 0.5f) * 255.0f;
                            int iR = (int)Red;
                            iR = iR > 255 ? 255 : iR;
                            iR = iR < 0 ? 0 : iR;
                            int iG = (int)Green;
                            iG = iG > 255 ? 255 : iG;
                            iG = iG < 0 ? 0 : iG;
                            int iB = (int)Blue;
                            iB = iB > 255 ? 255 : iB;
                            iB = iB < 0 ? 0 : iB;
                            row[columnOffset] = (byte)iB;
                            row[columnOffset + 1] = (byte)iG;
                            row[columnOffset + 2] = (byte)iR;
                            columnOffset += 4;
                        }
                        catch (AccessViolationException av)
                        {
                            MessageBox.Show("Access violation!");
                        }
                    }

                }
            } 
            NewBitmap.UnlockBits(data); 
            return NewBitmap; 
        }



它似乎工作正常.我可以加载图像并使用此方法进行调整.我还有另外两种不带有不安全代码的亮度和缩放方法.他们不会造成任何问题.无论如何,我似乎突然发现访问冲突仅在更改彩色图像时发生.它发生在此行:



It seemed to be working fine. I could load an image and make ajustments using this method. I have another two methods for brightness and scaling which don''t have unsafe code. They don''t cause any problems. Anyway, all of a sudden I seem to get an access violation that only occurs when altering colour images. It occurs in this line:

byte B = row[columnOffset];



但不是在第一次迭代中.例如,当我使用宽度= 1024,高度= 1184的图像时,当columnOffset达到3072时会发生错误.
对于问题所在,我一头雾水,当然应该将灰度图像与彩色图像一样对待.

帮助将不胜感激.

是的,我可以尝试另一种对比度调整方法.但我真的很想知道问题出在哪里-也许病态的好奇心...

谢谢,吉布.



But not in the first iteration. For example when I use an image that''s Width = 1024, Height = 1184, the error occurs when columnOffset reaches 3072.

I''m stuck for ideas as to what the problem is as surely it should treat a greyscale image the same as a colour one.

Help would be much appreciated.

And yes, I could try another contrast adjustment method, which I will. But I''d really like to know what the problem is here - morbid curiosity perhaps...

Thanks, Jib.

推荐答案

您确定图像是每个像素32位,而不是每个像素24位吗?检出PixelFormat并使用其大小.

Are you sure the image is 32 bit per pixel and not 24 bit per pixel? Check out the PixelFormat and use the size of that.

columnOffset += Image.GetPixelFormatSize(NewBitmap.PixelFormat);



http://msdn.microsoft.com/en-us/library/system. drawing.image.getpixelformatsize.aspx [ ^ ]

作为旁注:
此异常处理不是很有用,尤其是在调试过程中,因为每个异常都会导致Access冲突,即使它是其他情况.只需显示提出的错误或将其包含为技术错误"即可.进一步,您可以(也许应该)使用Debug.Write输出带有堆栈跟踪和所有内容的完整错误,因此您可以更轻松地进行检查.



http://msdn.microsoft.com/en-us/library/system.drawing.image.getpixelformatsize.aspx[^]

As side note:
This exception handling is not very helpful especially during debugging because every exception gives Access violation even if it is something else. Just show the error raised or include it as "technical error". Further you could (or maybe should) use Debug.Write to output the complete error with stack trace and everything so you can check it out more easy.

catch (AccessViolationException av)
{
    MessageBox.Show(String.Format("An error occured\nTechnical error: {0}"), av.Message));
}



祝你好运!



Good luck!


public static Bitmap AdjustContrast(Bitmap Image, float Value) 
        { 
            Value = (100.0f + Value) / 100.0f; 
            Value *= Value; 
            Bitmap NewBitmap = (Bitmap)Image.Clone(); 
            BitmapData data = NewBitmap.LockBits(new Rectangle(0, 0, NewBitmap.Width, NewBitmap.Height), ImageLockMode.ReadWrite, NewBitmap.PixelFormat);
            //BitmapData data = NewBitmap.LockBits(new Rectangle(0, 0, NewBitmap.Width, NewBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);


            int bitsPerPixel = (Bitmap.GetPixelFormatSize(Image.PixelFormat)) / 8;

            unsafe 
            {
                for (int y = 0; y < NewBitmap.Height; ++y)
                {
                    byte* row = (byte*)data.Scan0 + (y * data.Stride);
                    int columnOffset = 0;

                    for (int x = 0; x < NewBitmap.Width; ++x)
                    {
                        try
                        {
                            byte B = row[columnOffset];
                            byte G = row[columnOffset + 1];
                            byte R = row[columnOffset + 2];
                            float Red = R / 255.0f;
                            float Green = G / 255.0f;
                            float Blue = B / 255.0f;
                            Red = (((Red - 0.5f) * Value) + 0.5f) * 255.0f;
                            Green = (((Green - 0.5f) * Value) + 0.5f) * 255.0f;
                            Blue = (((Blue - 0.5f) * Value) + 0.5f) * 255.0f;
                            int iR = (int)Red;
                            iR = iR > 255 ? 255 : iR;
                            iR = iR < 0 ? 0 : iR;
                            int iG = (int)Green;
                            iG = iG > 255 ? 255 : iG;
                            iG = iG < 0 ? 0 : iG;
                            int iB = (int)Blue;
                            iB = iB > 255 ? 255 : iB;
                            iB = iB < 0 ? 0 : iB;
                            row[columnOffset] = (byte)iB;
                            row[columnOffset + 1] = (byte)iG;
                            row[columnOffset + 2] = (byte)iR;

                            columnOffset += bitsPerPixel;
                        }
                        catch (AccessViolationException av)
                        {
                            MessageBox.Show("Access violation!");
                        }
                    }
                    

                }
            } 
            NewBitmap.UnlockBits(data); 
            return NewBitmap; 
        }



请忽略try ctach块...

臂架



Please ignore the try ctach block...

Jib


这篇关于C#不安全代码-访问冲突-图像字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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