Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. c# Convert a large bitmap into jpeg format

c# Convert a large bitmap into jpeg format

Scheduled Pinned Locked Moved C#
graphicscsharpperformancehelptutorial
5 Posts 4 Posters 16 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mgulde
    wrote on last edited by
    #1

    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?

    D L L 3 Replies Last reply
    0
    • M mgulde

      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?

      D Offline
      D Offline
      darkDercane
      wrote on last edited by
      #2

      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

      1 Reply Last reply
      0
      • M mgulde

        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?

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        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.

        1 Reply Last reply
        0
        • M mgulde

          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?

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          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

          M 1 Reply Last reply
          0
          • L Luc Pattyn

            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

            M Offline
            M Offline
            mgulde
            wrote on last edited by
            #5

            @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.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups