更改图片的颜色,但只更改了一半 [英] Change color for a picture, but only changed half

查看:59
本文介绍了更改图片的颜色,但只更改了一半的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

重新粘贴完整的代码:

Re paste a complete code:

private void Adjust(Bitmap pBitmap, params int[] pValues)
        {
Prepare(pValues);
            BitmapData pBitmapData = pBitmap.LockBits(
                new Rectangle(0, 0, pBitmap.Width, pBitmap.Height),
                ImageLockMode.ReadWrite,
                PixelFormat.Format24bppRgb);

            byte[] pData = new byte[pBitmapData.Stride * pBitmapData.Height];
            Marshal.Copy(pBitmapData.Scan0, pData, 0, pData.Length);

            int iOffset = pBitmapData.Stride - pBitmapData.Width * 3;
            int iIndex = 0;

            for (int i = 0; i < pBitmapData.Height; i++)
            {
                for (int j = 0; j < pBitmapData.Width; j++)
                {
                    for (int k = iIndex; k < iIndex + 3; k++)
                    {
                        pData[k] = Adjust(pData[k], k);
                    }
                    iIndex += 3;
                }
                iIndex += iOffset;
            }

            Marshal.Copy(pData, 0, pBitmapData.Scan0, pData.Length);
}

protected void Prepare(int[] pValues)
        {
            m_iRed = pValues[0];
            m_iGreen = pValues[1];
            m_iBlue = pValues[2];
        }

 protected byte Adjust(byte iValue, int iIndex)
        {
            int nColour = 0;

            switch (iIndex % 3)
            {
                case 0:
                    nColour = (int)iValue + m_iBlue;
                    break;
                case 1:
                    nColour = (int)iValue + m_iGreen;
                    break;
                case 2:
                    nColour = (int)iValue + m_iRed;
                    break;
            }

          
            return Fix(nColour);
        }
  protected byte Fix(int iValue)
        {
            if (iValue < 0) iValue = 0;
            if (iValue > 255) iValue = 255;
            return (byte)iValue;
        }





我的尝试:



i将图片分为四个部分。我想通过RGB改变颜色。但只改变了一半。

1.当图片宽度小于256时,更改失败。 />
2.my小图片最大不超过256.

3.每张图片256 * 256都是正常的。

4.问题参数:r = 0,g = 0,b = 52。





对不起,我不知道如何在楼下回复。



关于Ralf Meier的解决方案

在更改像素循环时,我调试,图片的颜色并没有改变图片,它们是相同的值。



关于Jochen Arndt的解决方案

那时,代码没有完全粘贴,用于计算我修复过的值通过Fix。

更改为绝对值,仍然无效。

目前,我仍然没有发现问题。



图像设置r = 0,g = 0,b = 52时不改变颜色:https://i.stack.imgur.com/IIrgd.jpg



What I have tried:

i have a picture is divided into four parts.i want change color by RGB.but only changed half.
1.change failed when width of the picture less than 256.
2.my small picture maximum not more than 256.
3.Every picture of 256*256 is normal.
4.Problem parameter:r=0,g=0,b=52.


Sorry, I don't know how to reply downstairs.

about Ralf Meier's solution
On change pixel loop, I debug, the color of the picture and did not change the picture, they are the same value.

about Jochen Arndt's solution
At that time, the code did not paste completely, for the calculation of the value I have been repaired by Fix.
Changed to absolute value, still no effect.
At the moment, I still haven't found the problem.

the image does not change color when set r=0,g=0,b=52:https://i.stack.imgur.com/IIrgd.jpg

推荐答案

注意 BitmapData.Stride Property(System。 Drawing.Imaging) [ ^ ]将自下而上的位图为负数。所以你必须使用绝对值:

Note that the BitmapData.Stride Property (System.Drawing.Imaging)[^] will be negative with bottom-up bitmaps. So you have to use the absolute value:
int iStride = Math.Abs(pBitmapData.Stride);
byte[] pData = new byte[iStride * pBitmapData.Height];
int iOffset = iStride - pBitmapData.Width * 3;





另一个问题是使用 Adjust 函数中的字节索引来确定字节是否为R,G或B值。虽然这适用于第一行,但这不适用于其他行,因为行程(行的起始索引总是四的倍数,可能不会给出零模数)。所以你不应该传递索引,但 k - iIndex (或重写你的代码)。



我不喜欢知道以上是否是所见问题的来源(只改变了一半的颜色),但它们会导致错误的转换。





可能还有第三个问题:

您通过添加值来调整颜色而不检查溢出。当您的 m_iBlue 值为52时,每个大于203的蓝色值将变小。如果不是这样,你应该检查溢出并将结果设置为255:



Another problem is using the byte index in your Adjust function to determine if the byte is a R, G, or B value. While this will work for the first line this does not apply to others because of the stride (the start index of a line is always a multiple of four which may not give a zero modulo). So you should not pass the index but k - iIndex (or rewrite your code).

I don't know if the above are the source for the seen problem (changed only half of the colours) but they will result in wrong conversions.


There might be also a third problem:
You are adjusting colours by adding a value without checking for overflow. With your m_iBlue value of 52, each blue value greater than 203 will become smaller. If this is not intended you should check for overflows and set the result to 255:

protected byte Adjust(byte iValue, int iIndex)
{
    // ...
    return nColour > 255 ? 255 : nColour;
}



[/ EDIT]


[/EDIT]


这篇关于更改图片的颜色,但只更改了一半的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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