-1

Is it possible to write a bitmap in C# line by line? I am worried that using the Bitmap.Save() function will require too much memory when dealing with LARGE files..

To clarify, I want to do this:

  1. Open the file and write the bitmap header (if any)
  2. Put 1 scanline worth of image data into a buffer (byte[])
  3. Write the contents of the buffer into the file
  4. Repeat from 2 unless there are no more scan lines
  5. Close the file

How is this done in C#?

Thanks,

kreb

krebstar
  • 3,956
  • 8
  • 46
  • 64
  • are u sure, bitmap.save() requires large memory? – Benny Dec 28 '09 at 06:46
  • If you want to read one by one line, you need to implement the the decoding of the source file yourself. The built-in functions will load the whole image afaik. – Mikael Svenson Dec 28 '09 at 08:01
  • @Benny: Sorry, I meant that going the Bitmap.Save() route requires me to load the whole image into memory because I have to use a pointer to that memory block to save the file.. – krebstar Dec 28 '09 at 08:06
  • @Mikael: decoding of the source bitmap file is already done via c++, i just load the library and use its functions.. I'd like to know how to take these scanlines of data and write them to file line by line (so that my buffer size only has to be as big as a scan line, and not the whole image).. – krebstar Dec 28 '09 at 08:08
  • @krebstar That depends on the library you have :) If it can read one line at a time and pass you a byte array or something, then you write that. Question: Are you writing out as a raw image, or as some format, and could you post some code? – Mikael Svenson Dec 28 '09 at 08:27
  • @Mikael unfortunately my library only reads, does not write.. I was looking to use C# to write the bitmap.. I am writing out as a raw image.. Hold on I'll post some code as an answer.. – krebstar Dec 28 '09 at 08:55

2 Answers2

0

@Mikael

It looks like this:

int bufferSize = ((width +31) >> 5) << 2); // the width is in pixels, 1bpp,
// so I had to round up to the nearest 32 bits

byte[] buffer = new byte[bufferSize];
byte[] buffer = new byte[height * bufferSize];

for (int i = 0; i < height; i++)
{
    getLine(buffer,bufferSize);
    Buffer.BlockCopy(bufffer,0,bigBuffer, i*bufferSize, bufferSize);
}

unsafe
{
    fixed (byte* ptr = bigBuffer)
    {
        using (Bitmap image = new Bitmap(width,height,bufferSize,System.Drawing.Imaging.PixelFormat.Format1bbIndexed, new IntPtr(ptr)))
        {
            image.SetResolution(xres,yres);
            image.Save(filename,System.Drawing.Imaging.ImageFormat.Tiff);
        }
    }
}

I am worried that for really big images, bigBuffer might become too big.. I would like to change this to write to file line by line, instead of writing it in one go..

Thanks.. :)

krebstar
  • 3,956
  • 8
  • 46
  • 64
  • Ok, so the C++ library gives you decoded bytes, which you want to save as TIFF. If you want to save this line by line, you cannot use the built-in Bitmap class, but must find a library which supports writing chunk by chunk. Or you could persist bigbuffer as a Memory Mapped file, and have the IntPtr point to that instead. That would save you from physical memory usage. That said, 32bit .Net can hold data up to ~800mb before you get out of memory exceptions, and 64bit as much as you have (more or less). What data sizes are we talking about? – Mikael Svenson Dec 28 '09 at 09:12
  • Yes, that's right :) Really big.. I'm supposed to plan for 2GB files.. Could you give me an example or point me to a tutorial on memory mapped files? That sounds interesting and seems like it could be the key :) – krebstar Dec 28 '09 at 09:25
  • Check out http://github.com/tomasr/filemap/, or the new System.IO.MemoryMappedFiles namespace in .Net 4.0. You can also look at my http://mmf.codeplex.com project for usage. – Mikael Svenson Dec 28 '09 at 09:50
  • Thanks Mikael I'll check it out :) Happy holidays! :) – krebstar Dec 29 '09 at 00:51
  • One more question, even if I use memory mapped files, wouldn't I still require memory the size of the file if I use Bitmap.Save()? – krebstar Dec 31 '09 at 01:14
0

I was once writing some code that saved a 32kx32k pixels JPEG file. I had tons of problems with creating it, loading it, viewing it and manipulating it (Photoshop can handle files up to 30kx30k). After trying allot I dropped the whole deal and decided on saving parts of the big image to small images and write some manager program that knows how to "stitch" these files when needed.

I'm not sure when you are in to but if it is for display then you might check out DeepZoom

Gilad
  • 2,876
  • 5
  • 29
  • 40