0
votes

I'm making some Bitmap image manipulation application in c# so I need to implicitly convert image to bmp so I can manipulate it like byte[] (byte array). Problem appears when this image is not bmp format - in that case after I convert it to Bitmap and after I convert this Bitmap into byte[] and apply some functions (by the way I "avoided" first 53 bytes - the header bytes) app breaks and I get "Parameter is not valid" message while trying to instance new Bitmap using MemoryStream on this byte[].

This is the code:

public void load(PictureBox pom)
{
    OpenFileDialog o = new OpenFileDialog();

    //o.Filter = "bin files (*.bin)|*.bin";

    if (o.ShowDialog() == DialogResult.OK)
    {
        Bitmap b = (Bitmap)Image.FromFile(o.FileName);

        pom.Image = b;

        //pom.Image = new Bitmap(o.FileName);
        this.p = pom;
        this.input_bin_fajl = File.ReadAllBytes(o.FileName);
        this.output_bin_fajl = new byte[this.input_bin_fajl.Length];
    }
}

public static Bitmap ByteToImage(byte[] blob)
{
    using (MemoryStream mStream = new MemoryStream())
    {
        mStream.Write(blob, 0, blob.Length);
        mStream.Seek(0, SeekOrigin.Begin);

        // this is the breaking point
        Bitmap bm = new Bitmap(mStream);
        //

        return bm;
    }
}
1
"by the way I "avoided" first 53 bytes - the header bytes" - can you tell us more about that? That sounds like it's probably the problem... - Jon Skeet
First 53 bytes of BMP formatted image are header bytes after them goes bytes that describe pixels. So, in order to change image content you must leave this bytes untouched to preserve basic image information. - user3647695
But what makes you think that the Bitmap constructor would expect you to have removed the header first? It needs that information to know the size of the image, and potentially any compression. Basically, you should pass the whole data to the Bitmap constructor. It's not like the header is just junk bytes... - Jon Skeet
No, you misunderstood me - I skipped them in process of manipulation that's what I meant by avoiding them. What I wanted to say is that I haven't violated these bytes, yet I just copied them. - user3647695
Well if the header contains any sort of checksum information, that would certainly explain it. Also, does your "manipulation" make any sort of assumption about whether or not the data is compressed, etc? Usually you'd just load the data, then get an in-memory representation, modify that potentially, then save it as an image again. Perhaps you could provide a short but complete program demonstrating the problem? - Jon Skeet

1 Answers

0
votes

Here is the code it works with unsafe thanks again :)

    void preview(Bitmap bm, int i)
    {
        BitmapData bmData = bm.LockBits(new Rectangle(0,0,bm.Width,bm.Height), ImageLockMode.ReadWrite, bm.PixelFormat);
        int stride = bmData.Stride;
        System.IntPtr Scan0 = bmData.Scan0;

        unsafe
        {
            byte* p = (byte*)(void*)Scan0;
            int nOffset = stride - bm.Width * 3;
            int nWidth = bm.Width * 3;

            for (int y = 0; y < bm.Height; ++y)
            {
                for (int x = 0; x < bm.Width; ++x)
                {
                    switch (i)
                    {
                        case 0:
                            {
                                p[0] = (byte)0;
                                p[1] = (byte)0;
                                break;
                            }
                        case 1:
                            {
                                p[0] = (byte)0;
                                p[2] = (byte)0;
                                break;
                            }
                        default:
                            {
                                p[1] = (byte)0;
                                p[2] = (byte)0;
                                break;
                            }                               
                    }
                    p+=3;
                }
                p += nOffset;
            }
        }

        bm.UnlockBits(bmData);
    }