-1

i'm learning programming , and i'm stuck on this error for a long time

i tried changing variable to float

        Color col;
        float red, green, blue,gray;

        for (int i = 0; i < oImage.Width; i++)
            for (int j = 0; j < oImage.Height; j++)
            {
                col = oImage.GetPixel(i, j);
                red = col.R;
                green = col.G;
                blue = col.B;
                gray = red*0.21 + green*0.72 + blue*0.07;


             oImage.SetPixel(i, j, Color.FromArgb(gray, gray, gray));

            }

        picImage.Refresh();

i expect the output is to convert a normal photo to a luminosity background

  • 1
    Possible duplicate of [c# how to convert float to int](https://stackoverflow.com/questions/7173677/c-sharp-how-to-convert-float-to-int) – Avi Nov 06 '19 at 10:10
  • 1
    For the casual reader it would be nice to know what goes wrong: Do you get a compiler error? Do you get a runtime error? Or does the program compile and run but does not produce the expected result? – Peter - Reinstate Monica Nov 06 '19 at 10:22
  • I also frown upon questions which are easily googleable. When I google "c# convert float to int" I get a number of useful answers. Among them (admittedly at rank 12) is the [canonical documentation from microsoft.](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions): "There exists a conversion between any two numeric types, either implicit or explicit. You must use the cast operator () to invoke an explicit conversion." ... "**Explicit numeric conversions:** ... From float to sbyte, byte, short, ushort, int, uint, long, ulong, or decimal". – Peter - Reinstate Monica Nov 06 '19 at 10:26

2 Answers2

4

replace

gray = red*0.21 + green*0.72 + blue*0.07;
....
oImage.SetPixel(i, j, Color.FromArgb(gray, gray, gray));

with

gray = red * 0.21f + green * 0.72f + blue * 0.07f;
...
oImage.SetPixel(i, j, Color.FromArgb((int)gray, (int)gray, (int)gray));
  • 0.21 is recognized as double. If you add a f it will mark the value as float Reference:

The literal without suffix or with the d or D suffix is of type double

The literal with the f or F suffix is of type float

The literal with the m or M suffix is of type decimal

  • float can be casted into int so (int)myFloatValue works
Community
  • 1
  • 1
fubo
  • 44,811
  • 17
  • 103
  • 137
0

You should make gray a byte and explicitly cast the formula to byte.

byte gray = (byte) (red*0.21 + green*0.72 + blue*0.07);

Please note the restriction on the values passed to FromArgb(Int32, Int32, Int32)

(...) Although this method allows a 32-bit value to be passed for each color component, the value of each component is limited to 8 bits.


Note 1. bytes, floats, doubles, and ints

You declare red, green, blue as floats where in fact they're bytes.

They don't need to be floats because a float/double * a byte becomes a float/double.

Consider the following snippet.

Color col = Color.FromKnownColor(KnownColor.Salmon);
var red = col.R;
var xR = 0.21;
var grayR = col.R*xR;

This prints

'red' is System.Byte: 250
'xR' is System.Double: 0.21
'grayR' is System.Double: 52.5

Note 2. Less variables

You can simplify the code by using the RGB values directly in the formula.

Color col = Color.FromKnownColor(KnownColor.Salmon);
byte gray = (byte) (col.R*0.21 + col.G*0.72 + col.B*0.07);
Color c2 = Color.FromArgb(gray, gray, gray);
tymtam
  • 31,798
  • 8
  • 86
  • 126
  • 1
    thank you soo much.My error was "cannot implicity convert type 'double' to 'float'.".i change the variable to double instead of float .And i do this "oImage.SetPixel(i, j, Color.FromArgb((int)gray, (int)gray, (int)gray));" it works, thx for sovling my problem – ilikeurstyle Nov 06 '19 at 15:06