位图创建问题(无效参数)C#

时间:2015-08-14 04:15:50

标签: c# winforms graphics bitmap

好。这是源代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;

namespace PictureMaker
{
class Program
{
    static void Main()
    {
        int[] WorkingSet = new int[2] { 1, 1 }; //used for rng
        int[] Pixel = new int[3] { 0, 0, 0 }; // rgb value of pixel from rng
        byte[] Data; //raw data to be put into memory
        int Height; //height of final image
        int Width; //width of final image
        Bitmap Picture; //picture to save
        string Input; //input storage string
        int RandomNumber = 0; //inital random number
        byte[] MinorData; //temporary data storage

        Console.WriteLine("Seed 1 (100 to 999, whole numbers only):");
        Input = Console.ReadLine(); //gets input
        WorkingSet[0] = int.Parse(Input); //parses to variable
        Console.WriteLine("Seed 2 (100 to 999, whole numbers only):");
        Input = Console.ReadLine();
        WorkingSet[1] = int.Parse(Input);
        Console.WriteLine("Height (whole numbers only):");
        Input = Console.ReadLine();
        Height = int.Parse(Input);
        Console.WriteLine("Width (whole numbers only):");
        Input = Console.ReadLine();
        Width = int.Parse(Input);

        Data = new byte[Height * Width * 4]; //width times height times pixel byte depth makes total bytes required to store the image.

        for (int i = (Height * Width * 4) - 1; i >= 0; i = i - 4) //each loop makes a single pixel, so it creates 4 bytes. Starting with the last pixel and moving to the first pixel.
        {
            WorkingSet = GenerateRandomNumber(WorkingSet);
            RandomNumber = WorkingSet[1]; //uses the second (fresh) number from the working set to use in making the pixel.
            MinorData = GeneratePixel(RandomNumber); //assigns pixel data to the temporary storage

            Data[i] = (byte)0;  //alpha channel is always 0 (I hope)
            Data[i - 1] = MinorData[2];
            Data[i - 2] = MinorData[1]; //remember this is backwards. last pixel to first pixel.
            Data[i - 3] = MinorData[0];
        }

        IntPtr Pointer = System.Runtime.InteropServices.Marshal.AllocHGlobal((Height * Width) * 4); //?? assigns the proper number of bytes to be stored in memory at this location ?? no idea honestly
        for (int i = (Height * Width * 4) - 1; i >= 0; i = i - 1) //iderates through each byte in the data...
        {
            System.Runtime.InteropServices.Marshal.WriteByte(Pointer, i + 1, Data[i]); //... and writes them one at a time to the 'reserved memory'; also hopefully moves the writer to a 'fresh' memory byte each time. No idea.
        }

        try //put all this here because it was crashing.
        {
            Picture = new Bitmap(Width, Height, Width * 4, System.Drawing.Imaging.PixelFormat.Canonical, Pointer); //invalid parameter. 
            Picture.Save("MyPicture.bmp");
        }
        catch (ArgumentException s)
        {
            Console.WriteLine(s);
        }
        Console.ReadLine(); //keeps program from closing on completion.
    }

    static byte[] GeneratePixel(int RandomNumber)
    {
        //*28
        char[] CharArray; //for working with the number
        byte[] PixelData = new byte[3]; //for return
        CharArray = (RandomNumber.ToString().ToCharArray()); //converts number to string then breaks down to chars
        PixelData[0] = (byte)(int.Parse(CharArray[0].ToString())*28); //converts chars to string to number and multiplies by 28 then converts the 255 RGB int to a byte
        PixelData[1] = (byte)(int.Parse(CharArray[1].ToString())*28);
        PixelData[2] = (byte)(int.Parse(CharArray[2].ToString())*28);
        return PixelData;
    }

    static int[] GenerateRandomNumber(int[] WorkingSet)
    {
        int[] RandomNumber = new int[2]; //for return
        string RandomString; //for working
        RandomNumber[0] = WorkingSet[1]; //makes 2nd working set number the first
        RandomString = (WorkingSet[0] + WorkingSet[1]).ToString(); //generates next number
        RandomNumber[1] = int.Parse(RandomString.Substring(RandomString.Length - 3)); //gets last 3 numbers and assigns it to 2nd slot
        return RandomNumber; //returns as the new working set
    }
}
}

我试图在程序上生成一张图片(称之为抽象艺术),并将其写入磁盘。我并不真的需要程序生成部分的帮助。我想帮助将我的图像放到磁盘上。

Visual Studio给我的唯一一件事是:

  

System.ArgumentException:参数无效。在System.Drawing.Bitmap..ctor(Int32宽度,Int32高度,Int32步幅,PixelFormat格式,IntPtr scan0)

2 个答案:

答案 0 :(得分:1)

可能你的宽度和高度太高了。尝试使用较小的宽度和高度(600x800)并查看。 .NET可能会拒绝创建一次占用大量连续内存的图像。

答案 1 :(得分:1)

好吧,我开始使用100x200大小的代码。并且sids 200-300。 我没有发现你的错误,但发现了另一个:

  

System.AccessViolationException:尝试读取或写入受保护的内存

要解决此问题,我将PixelFormat更改为Format32bppRgb

 Picture = new Bitmap(Width, Height, Width * 4, System.Drawing.Imaging.PixelFormat.Format32bppRgb, Pointer); //invalid parameter. 

发生这种情况是因为某些类型的PixelFormat在传递给新的Bitmap()时会导致ArgumentException。以下是这些类型的列表:

  • GDI
  • α
  • PAlpha
  • 扩展
  • 典型
  • 未定义
  • dontCare项