2

I'm trying to make a script that compares a list of images to one comparison image and writes the filename of an image that is different. I made it a console application since I didn't need to display any images. I added the System.Drawing reference, however when I run my code I get the message: ArgumentException: Parameter is not valid.

Details:

System.TypeInitializationException
  HResult=0x80131534
  Message=The type initializer for 'ConsoleApp2.Program' threw an exception.
  Source=<Cannot evaluate the exception source>
  StackTrace:
<Cannot evaluate the exception stack trace>

Inner Exception 1:
ArgumentException: Parameter is not valid.

The output says:

Exception thrown: 'System.ArgumentException' in System.Drawing.dll An unhandled exception of type 'System.TypeInitializationException' occurred in Unknown Module. The type initializer for 'ConsoleApp2.Program' threw an exception.

I'm not sure why the exception is being thrown. Removing the reference to System.Drawing and commenting all of the code that uses bitmaps stops the exception, although that is not very useful.

This is the code I'm running:

static Bitmap comparison = new Bitmap("Comparison.jpg");
static void Main(string[] args)
{
    string[] fileArray = Directory.GetFiles(filepath);

    string compare = AnalyzeBitmap(comparison);

    foreach(string file in fileArray)
    {
        Bitmap hold = null;
        hold = new Bitmap(file);
        AnalyzeBitmap(hold);
        if (hold.Equals(compare))
        {
            Console.WriteLine(file);        
        }
    }

    Console.ReadKey();
}
AnalyzeBitmap():
static string AnalyzeBitmap(Bitmap bmp)
{
    var data = bmp.LockBits(
                           new Rectangle(Point.Empty, comparison.Size),
                           ImageLockMode.ReadWrite, 
                           comparison.PixelFormat
                           );

    var pixelSize = data.PixelFormat == PixelFormat.Format32bppArgb ? 4 : 3;
    var padding = data.Stride - (data.Width * pixelSize);
    var bytes = new byte[data.Height * data.Stride];

    // copy the bytes from bitmap to array
    Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);

    var index = 0;
    var builder = new StringBuilder();

    for (var y = 0; y < data.Height; y++)
    {
        for (var x = 0; x < data.Width; x++)
        {
            Color pixelColor = Color.FromArgb(
                            pixelSize == 3 ? 255 : bytes[index + 3], // A component if present
                            bytes[index + 2], // R component
                            bytes[index + 1], // G component
                            bytes[index]      // B component
                            );

            builder
                   .Append("  ")
                   .Append(pixelColor.R)
                   .Append("     ")
                   .Append(pixelColor.G)
                   .Append("     ")
                   .Append(pixelColor.B)
                   .Append("     ")
                   .Append(pixelColor.A)
                   .AppendLine();



            index += pixelSize;
        }

        index += padding;
    }

    // copy back the bytes from array to the bitmap
    Marshal.Copy(bytes, 0, data.Scan0, bytes.Length);

    return builder.ToString();

}
Martin Verjans
  • 4,675
  • 1
  • 21
  • 48

1 Answers1

1

The problem is this line

static Bitmap comparison = new Bitmap("Comparison.jpg");

because a TypeInitializationException is an internal exception which is only thrown when an exception happens in a static constructor or in a static field initializer. In your case, there is no static constructor and just that static field initializer.

I think the specified file does not exist. Please check if there is a file called Comparison.jpg in the output path of your application.

You should also wrap your Bitmap instances in a using statement and therefore convert the static Bitmap to a local variable. See: What are the uses of "using" in C#

ZeiTee
  • 164
  • 2
  • 7
  • That line should not raise this exception but rather a FileNotFoundException() – Martin Verjans Jun 04 '19 at 06:02
  • Yes, but I tried it and it actually raises an ArgumentException. – ZeiTee Jun 04 '19 at 06:09
  • You are correct my mistake. Maybe you can add the following precision, the internal Exception is TypeInitializationException because the first call to new Bitmap is the static call, which is actually the very first operation executed – Martin Verjans Jun 04 '19 at 06:18