c# Convert a large bitmap into jpeg format
-
Hello all, I am currently handling very large images, which are basically generated by stitching together many smaller images (e.g. panorama or photo mosaic software). In order to avoid out-of-memory exceptions (in memory are only "maps" of how to arrange the smaller images), I wrote some code saving these images line by line as bitmaps using BinaryWriter and LockBits. So far, so good. The problem is now that I would like to save these images as Jpegs (or PNGs) as well. Since I am pretty new to c# I can only think of two ways for now: 1) Similar to the bitmap saving procedure. Generating some jpeg header and saving the big images line by line, compressing them somehow before. I have no idea how to perform the compression though. 2) Streaming the already saved bitmap into the memory and saving it as encoded jpeg. Since the second approach seemed easier, I tried something like this:
FileStream fsr = new FileStream("input.bmp", FileMode.Open, FileAccess.Read);
FileStream fsw = new FileStream("output.jpg", FileMode.CreateNew, FileAccess.Write);EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 80L);Bitmap bmp = new Bitmap(fsr);
bmp.Save(fsw, GetEncoder(ImageFormat.Jpeg), encoderParameters);bmp.Dispose();
The problem is now that the save-method tries to completely load the bitmap into memory first, causing an out-of-memory exception. I would be more than happy for any suggestions on how to solve or circumvent this problem! Cheers, Max Update: I now edited the code so that it saves bands of 8 lines as bmp. These bands I would now like to save to the same jpeg file - any ideas?
-
Hello all, I am currently handling very large images, which are basically generated by stitching together many smaller images (e.g. panorama or photo mosaic software). In order to avoid out-of-memory exceptions (in memory are only "maps" of how to arrange the smaller images), I wrote some code saving these images line by line as bitmaps using BinaryWriter and LockBits. So far, so good. The problem is now that I would like to save these images as Jpegs (or PNGs) as well. Since I am pretty new to c# I can only think of two ways for now: 1) Similar to the bitmap saving procedure. Generating some jpeg header and saving the big images line by line, compressing them somehow before. I have no idea how to perform the compression though. 2) Streaming the already saved bitmap into the memory and saving it as encoded jpeg. Since the second approach seemed easier, I tried something like this:
FileStream fsr = new FileStream("input.bmp", FileMode.Open, FileAccess.Read);
FileStream fsw = new FileStream("output.jpg", FileMode.CreateNew, FileAccess.Write);EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 80L);Bitmap bmp = new Bitmap(fsr);
bmp.Save(fsw, GetEncoder(ImageFormat.Jpeg), encoderParameters);bmp.Dispose();
The problem is now that the save-method tries to completely load the bitmap into memory first, causing an out-of-memory exception. I would be more than happy for any suggestions on how to solve or circumvent this problem! Cheers, Max Update: I now edited the code so that it saves bands of 8 lines as bmp. These bands I would now like to save to the same jpeg file - any ideas?
may be u can reduce the quality of your image so u can compress it, cos only put a header of jpg doesn't mean that automatically compress it to a jpg file size... here is a link in vb.net http://www.vbforums.com/showthread.php?p=2038488#post2038488[^] Good luck
-
Hello all, I am currently handling very large images, which are basically generated by stitching together many smaller images (e.g. panorama or photo mosaic software). In order to avoid out-of-memory exceptions (in memory are only "maps" of how to arrange the smaller images), I wrote some code saving these images line by line as bitmaps using BinaryWriter and LockBits. So far, so good. The problem is now that I would like to save these images as Jpegs (or PNGs) as well. Since I am pretty new to c# I can only think of two ways for now: 1) Similar to the bitmap saving procedure. Generating some jpeg header and saving the big images line by line, compressing them somehow before. I have no idea how to perform the compression though. 2) Streaming the already saved bitmap into the memory and saving it as encoded jpeg. Since the second approach seemed easier, I tried something like this:
FileStream fsr = new FileStream("input.bmp", FileMode.Open, FileAccess.Read);
FileStream fsw = new FileStream("output.jpg", FileMode.CreateNew, FileAccess.Write);EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 80L);Bitmap bmp = new Bitmap(fsr);
bmp.Save(fsw, GetEncoder(ImageFormat.Jpeg), encoderParameters);bmp.Dispose();
The problem is now that the save-method tries to completely load the bitmap into memory first, causing an out-of-memory exception. I would be more than happy for any suggestions on how to solve or circumvent this problem! Cheers, Max Update: I now edited the code so that it saves bands of 8 lines as bmp. These bands I would now like to save to the same jpeg file - any ideas?
Well, that's what it does. A third party encoder may be worth looking into, or you can roll your own. PNG is pretty easy to encode in a streaming way (the Deflate step obviously requires a buffer, but a constant-size small one). JPG of course can't exactly be encoded line-by-line, but block by block isn't any worse.
-
Hello all, I am currently handling very large images, which are basically generated by stitching together many smaller images (e.g. panorama or photo mosaic software). In order to avoid out-of-memory exceptions (in memory are only "maps" of how to arrange the smaller images), I wrote some code saving these images line by line as bitmaps using BinaryWriter and LockBits. So far, so good. The problem is now that I would like to save these images as Jpegs (or PNGs) as well. Since I am pretty new to c# I can only think of two ways for now: 1) Similar to the bitmap saving procedure. Generating some jpeg header and saving the big images line by line, compressing them somehow before. I have no idea how to perform the compression though. 2) Streaming the already saved bitmap into the memory and saving it as encoded jpeg. Since the second approach seemed easier, I tried something like this:
FileStream fsr = new FileStream("input.bmp", FileMode.Open, FileAccess.Read);
FileStream fsw = new FileStream("output.jpg", FileMode.CreateNew, FileAccess.Write);EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 80L);Bitmap bmp = new Bitmap(fsr);
bmp.Save(fsw, GetEncoder(ImageFormat.Jpeg), encoderParameters);bmp.Dispose();
The problem is now that the save-method tries to completely load the bitmap into memory first, causing an out-of-memory exception. I would be more than happy for any suggestions on how to solve or circumvent this problem! Cheers, Max Update: I now edited the code so that it saves bands of 8 lines as bmp. These bands I would now like to save to the same jpeg file - any ideas?
You can't get decent JPEG compression for images with insufficient height, the DCT step in the JPEG compression algorithm is using pixel blocks of 8 by 8 pixels. Any less will fail terribly. Are you sure you are actually running out of memory? How many elementary images are there, and what is their size? The reason I ask is GDI+ tends to be pretty confusing with its error messages, e.g. when Image.FromFile() says "out-of-memory" it really means "this is an image format I don't understand". See here[^]. :)
Luc Pattyn [My Articles] Nil Volentibus Arduum
-
You can't get decent JPEG compression for images with insufficient height, the DCT step in the JPEG compression algorithm is using pixel blocks of 8 by 8 pixels. Any less will fail terribly. Are you sure you are actually running out of memory? How many elementary images are there, and what is their size? The reason I ask is GDI+ tends to be pretty confusing with its error messages, e.g. when Image.FromFile() says "out-of-memory" it really means "this is an image format I don't understand". See here[^]. :)
Luc Pattyn [My Articles] Nil Volentibus Arduum
@darkDercane: Yes, I would like to compress it. The problem is that I do not know how to do this chunk by chunk. @harold aptroot: Do you by chance know of any example on how to encode (and save) a picture block-by-block? @Luc Pattyn: It would be no problem to hand the compression algorithm blocks of 8x8 pixels, I chose to do it linewise for no real reason. Assuming that I deliver chunks of 8x8 or bigger, how can I encode these chunks into one JPG (or PNG) file? And yes, I am pretty sure, I am really running out of memory. The filesize of each elementary image is about 10k px (e.g. 100x100), there could be sth like10 to 100k of them in the final image. I recently tested the program by saving the resulting image on hdd and got a 1.7 GB (32bpp) bmp monster image file. I do not plan to exceed the 32kpx limit of bmp though.