0

我正在尝试将图像的红色值增加 50%。这是我的代码:

public static Bitmap IncreaseRedFiftyPercent(Bitmap b)
    {
        Bitmap temp = (Bitmap) b;
        Bitmap bmap = (Bitmap)temp.Clone();
        Color c;
        for (int i = 0; i < bmap.Width; i++)
        {
            for (int j = 0; j < bmap.Height; j++)
            {
                c = bmap.GetPixel(i, j);
                byte increase = c.R + c.R * 0.5;  //This line gives error

                bmap.SetPixel(i, j, Color.FromArgb(increase, c.G, c.B));
            }
        }
        b = (Bitmap)bmap.Clone();
        return b;
    }

这是我所做的:我读取图片的所有像素,并将红色值增加百分之五十并保持蓝色和绿色相同。但是线

byte increase = c.R + c.R * 0.5;  //This line gives error

给我一个错误说

Cannot implicitly convert type 'double' to 'byte'. An explicit conversion exists (are you missing     
a cast?)    

而且我不能将双精度转换为字节?我在做什么看起来很明智,这里有什么问题?

谢谢

4

3 回答 3

8

C# 中的算术运算首先通过从可能的运算符列表中选择来确定要使用的运算符:

int * int --> int
long * long --> long
double * double --> double

等等; 这份清单很长。

在您的情况下,最好的运算符是double * double --> double,因此字节被转换为双精度。这是无损的。但结果是双倍的;它可能有一个小数部分,并且它的大小可能大于最大可能的字节。转换回字节是有损的。因此,您需要通过插入转换为字节来说“我保证我真的想要进行这种有损转换”。

现在,在你这样做之前,你应该确保你实际上在做正确的事情!如果字节已经是 200,那么将其增加 50% 到双倍 300.00,然后将其转换回只能介于 0 和 255 之间的字节可能会产生意想不到的结果。在插入该演员表之前请仔细考虑。

于 2013-10-01T22:41:31.170 回答
5

您可以改用它,尽管它不会考虑溢出(任何超过 255 的结果都将翻转为 0):

byte increase = (byte)(c.R + c.R / 2);

请注意,我使用/2而不是*0.5使用整数数学而不是浮点数学。如果您正在处理大量大图像,则性能差异可能会很大。

根据您的要求,这样的事情可能会起作用:

byte increase = (byte)(Math.Min(c.R + c.R / 2 , 255));
于 2013-10-01T22:37:43.450 回答
1

问题是当你取一个字节(例如c.R)并乘以一个双精度(例如0.5)时,结果是一个双精度(因为一个字节可能没有保存结果的精度)。然后您尝试将其分配给一个字节,并且错误消息说不存在隐式转换,因此您必须显式转换它。

这可以用类似的东西来完成

byte increase = (byte)(c.R + c.R * 0.5);

另一个答案提醒我,这不会检查溢出,所以如果c.R超过 170,那么你会遇到溢出问题。为此,您需要执行 D Stanley 的 Min 技术。

于 2013-10-01T22:38:29.437 回答