The value was either too small or too large for an unsigned byte C#

6.6k Views Asked by At

I have 2 methods, shown below, and i can't get it to work. I am trying to open a .png file from a OpenFileDialog and display it on a ImageBox:

public static Bitmap ToBitmap(this string input)
{
    List<byte> splitBytes = new List<byte>();
    string byteString = "";
    foreach (char i in input)
    {
        byteString += i;
        if (byteString.Length == 3)
        {
            splitBytes.Add(Convert.ToByte(byteString));
            byteString = "";
        }
    }
    if (byteString != "")
        splitBytes.AddRange(Encoding.ASCII.GetBytes(byteString));
    using (var ms = new MemoryStream(splitBytes.ToArray()))
    {
        var img = Image.FromStream(ms);
        Bitmap output = new Bitmap(img);
        return output;
    }
}

public static string StringFromFile(string input)
{
    StreamReader sr = new StreamReader(input);
    string file = string.Empty;
    while (sr.EndOfStream == false)
    {
        file += sr.Read();
    }
    return file;
}

In another file i tried to use the method:

OpenFileDialog OFD = new OpenFileDialog();
OFD.Filter = "Images (*.png)|*.png";
OFD.ShowDialog();
pictureBox1.BackgroundImageLayout = ImageLayout.Stretch;
pictureBox1.BackgroundImage = StringToBitmapConverter.ToBitmap(StringToBitmapConverter.StringFromFile(OFD.FileName));

But I get this exception:

System.OverflowException: 'Value was either too large or too small for an unsigned byte.'

Please help! I am using these methods in a class called StringToBitmapConverter, and there is an error that is giving me trouble, can anyone help me?

3

There are 3 best solutions below

4
Jason Boyd On

So according to the documentation Convert.ToByte(string value):

Converts the specified string representation of a number to an equivalent 8-bit unsigned integer.

And the method will throw an OverflowException if:

value represents a number that is less than Byte.MinValue or greater than Byte.MaxValue.

So the value of byteString must be less than 0 or greater than 255 at this line:

splitBytes.Add(Convert.ToByte(byteString));

2
Patrick Artner On

You could use try { } catch to catch the error or use byte.TryParse to only convert those numbers that are actually convertable.

Reading text from a File can be done by File.ReadAllText

Your algorythm splits the read text into characterblocks of 3 and interprets the text as byte:

"23405716119228936" -> 234,57,161,192,289,36 .... 289 does notfit into a byte -> exception. Check the files content.

if (byte.TryParse(byteString, out var b))
{
    splitBytes.Add(b);
}
else
{
    // this thing is not convertable to byte, do something with it....
}

Edit#1:

I guess reading in PNG-Files as "string" and converting them as you do does not work.

PNG Files have an internal format, they are encoded. See https://www.w3.org/TR/PNG/ or https://de.wikipedia.org/wiki/Portable_Network_Graphics

They are not strings that you can simply group into 3 chars, convert to byte and reinterprete as memory string.

For giggles try this on your file to see what is your input.:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

internal class Program
{
    static void Main(string[] args)
    {
        foreach (var s in Make3CharChunks(File.ReadAllText( /*your file path here*/ ""))
            Console.WriteLine(s);

        Console.ReadLine();
    }

    static IEnumerable<string> Make3CharChunks(string s)
                        => s.Aggregate(new List<string>(), (acc, c) =>
                {
                    if (acc.Any() && acc.Last().Count() < 3)
                        acc[acc.Count - 1] = $"{acc.Last()}{c}";
                    else
                        acc.Add(c.ToString());

                    return acc;
                });
}
1
Scott Chamberlain On

If all you are doing is trying to open a png you can throw away most all of your code and simplify it to

OpenFileDialog OFD = new OpenFileDialog();
OFD.Filter = "Images (*.png)|*.png";
var result = OFD.ShowDialog()    
if(result == DialogResult.OK) //You need to check to see if they clicked OK or Cancel.
{
    pictureBox1.BackgroundImageLayout = ImageLayout.Stretch;

    var oldImage = pictureBox1.BackgroundImage
    pictureBox1.Image = new Bitmap(OFD.FileName); //Shouold be Image, not BackgroundImage for a picture box.
    if(oldImage != null)
    {
        oldImage.Dispose();
    }

}