OutOfMemory Exception on saving image

E

ELandry

I am trying to convert an image to a bitonal image and am getting am
OutOfMemory exception. Below is the method that I am using. I am passing in
a byte array as an image, attempting to convert it to a B&W bitonal image or
bitmap, then return the byte array of the converted image. Error is occuring
on the line with the "TODO" comment.

private byte[] createBlackAndWhiteImageFromBuffer(byte[] buffer)
{
string tempfilename = Path.Combine(Path.GetTempPath(),
String.Format("{0}.tif", Guid.NewGuid()));

Bitmap image = (Bitmap)Bitmap.FromStream(new
MemoryStream(buffer, 0, buffer.Length));

buffer = null;

GC.Collect();

Guid objGuid = image.FrameDimensionsList[0];
FrameDimension objDimension = new FrameDimension(objGuid);

System.Drawing.Imaging.Encoder encoder =
System.Drawing.Imaging.Encoder.SaveFlag;

ImageCodecInfo info = GetEncoderInfo("image/tiff");

Bitmap pagebitmap = null;

using (MemoryStream str = new MemoryStream())
{
try
{
EncoderParameters ep = new EncoderParameters(2);

ep.Param[1] = new EncoderParameter(encoder,
(long)EncoderValue.CompressionCCITT4);

for (int i = 0; i < image.GetFrameCount(objDimension);
i++)
{
image.SelectActiveFrame(FrameDimension.Page, i);

if (i == 0)
{
pagebitmap = image.Clone(new Rectangle(0, 0,
image.Width, image.Height), PixelFormat.Format1bppIndexed); //TODO: Out of
Memory exception

ep.Param[0] = new EncoderParameter(encoder,
(long)EncoderValue.MultiFrame);
pagebitmap.Save(tempfilename, info, ep);
}
else
{
using (MemoryStream mstream = new MemoryStream())
{
ep.Param[0] = new EncoderParameter(encoder,
(long)EncoderValue.FrameDimensionPage);
image.Save(mstream, ImageFormat.Bmp);

using (Bitmap tempbmp =
((Bitmap)Bitmap.FromStream(mstream)).Clone(new Rectangle(0, 0, image.Width,
image.Height), PixelFormat.Format1bppIndexed))
{
pagebitmap.SaveAdd(tempbmp, ep);
}
}
}

if (i == (image.GetFrameCount(objDimension) - 1))
{
ep.Param[0] = new EncoderParameter(encoder,
(long)EncoderValue.Flush);
pagebitmap.SaveAdd(ep);
}
}



using (FileStream reader = new FileStream(tempfilename,
FileMode.Open, FileAccess.Read))
{

buffer = new byte[reader.Length];

reader.Read(buffer, 0, (int)reader.Length);

reader.Close();
}
}
finally
{
GC.Collect();

if (pagebitmap != null)
{
pagebitmap.Dispose();
}

if (image != null)
{
image.Dispose();
}

if (File.Exists(tempfilename))
{
File.Delete(tempfilename);
}

GC.Collect();
}
}
return buffer;
}
 
P

Peter Duniho

ELandry said:
I am trying to convert an image to a bitonal image and am getting am
OutOfMemory exception. Below is the method that I am using. I am passing in
a byte array as an image, attempting to convert it to a B&W bitonal image or
bitmap, then return the byte array of the converted image. Error is occuring
on the line with the "TODO" comment.

I didn't bother to look at the code closely. It doesn't look like you
have posted the minimal code example required to reproduce the problem,
and in any case without indentation, it's just not worth the
trouble...too hard to read.

But, I can tell you that due to the dependency on GDI+ for image
handling, unfortunately often the error returned is "out of memory" even
when the real problem is something else (usually, for example,
attempting to process an image using a format that's not supported by
GDI+ for that operation).

Pete
 
O

Oleg O

Publish complete exception information with call stack, because GDI+ classes can throw OutOfMemory exception to many cases

http://www.google.com/search?q=OutO...=t&rls=org.mozilla:ru:official&client=firefox



ELandry wrote:

OutOfMemory Exception on saving image
20-???-09

I am trying to convert an image to a bitonal image and am getting a
OutOfMemory exception. Below is the method that I am using. I am passing i
a byte array as an image, attempting to convert it to a B&W bitonal image o
bitmap, then return the byte array of the converted image. Error is occurin
on the line with the "TODO" comment

private byte[] createBlackAndWhiteImageFromBuffer(byte[] buffer

string tempfilename = Path.Combine(Path.GetTempPath()
String.Format("{0}.tif", Guid.NewGuid()))

Bitmap image = (Bitmap)Bitmap.FromStream(ne
MemoryStream(buffer, 0, buffer.Length))

buffer = null

GC.Collect()

Guid objGuid = image.FrameDimensionsList[0]
FrameDimension objDimension = new FrameDimension(objGuid)

System.Drawing.Imaging.Encoder encoder
System.Drawing.Imaging.Encoder.SaveFlag

ImageCodecInfo info = GetEncoderInfo("image/tiff")

Bitmap pagebitmap = null

using (MemoryStream str = new MemoryStream()

tr

EncoderParameters ep = new EncoderParameters(2)

ep.Param[1] = new EncoderParameter(encoder
(long)EncoderValue.CompressionCCITT4)

for (int i = 0; i < image.GetFrameCount(objDimension)
i++

image.SelectActiveFrame(FrameDimension.Page, i)

if (i == 0

pagebitmap = image.Clone(new Rectangle(0, 0
image.Width, image.Height), PixelFormat.Format1bppIndexed); //TODO: Out o
Memory exceptio

ep.Param[0] = new EncoderParameter(encoder
(long)EncoderValue.MultiFrame)
pagebitmap.Save(tempfilename, info, ep)

els

using (MemoryStream mstream = new MemoryStream()

ep.Param[0] = new EncoderParameter(encoder
(long)EncoderValue.FrameDimensionPage)
image.Save(mstream, ImageFormat.Bmp)

using (Bitmap tempbmp
((Bitmap)Bitmap.FromStream(mstream)).Clone(new Rectangle(0, 0, image.Width
image.Height), PixelFormat.Format1bppIndexed)

pagebitmap.SaveAdd(tempbmp, ep)




if (i == (image.GetFrameCount(objDimension) - 1)

ep.Param[0] = new EncoderParameter(encoder
(long)EncoderValue.Flush)
pagebitmap.SaveAdd(ep)




using (FileStream reader = new FileStream(tempfilename
FileMode.Open, FileAccess.Read)


buffer = new byte[reader.Length]

reader.Read(buffer, 0, (int)reader.Length)

reader.Close()


finall

GC.Collect()

if (pagebitmap != null

pagebitmap.Dispose()


if (image != null)

Previous Posts In This Thread:

EggHeadCafe - Software Developer Portal of Choice
JavaScript - Modal Dialog Box - Cross Browser
http://www.eggheadcafe.com/tutorial...c8-0f561ff9f681/javascript--modal-dialog.aspx
 

SSK

Joined
Oct 27, 2009
Messages
1
Reaction score
0
(e-mail address removed)

Hi ELandry

pagebitmap = image.Clone(new Rectangle(0, 0
image.Width, image.Height), PixelFormat.Format1bppIndexed); //TODO: Out o
Memory exceptio

the solution is :

Replace the above code with the below code and Add the ConvertToBlackAndWhite method to project.

ConvertToBlackAndWhite(image, ref pagebitmap );




// Code block
publicvoid ConvertToBlackAndWhite(Bitmap original, refBitmap destination)

{

float hr = (float)original.VerticalResolution;

Size iSize = newSize(original.Width, original.Height);

BitmapData sourceData = original.LockBits(newRectangle(0, 0, iSize.Width, iSize.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

int imageSize = sourceData.Stride * sourceData.Height;

byte[] sourceBuffer = newbyte[imageSize + 1];

Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);

original.UnlockBits(sourceData);

if (destination != null)

{

destination.Dispose();

GC.Collect(2);

}

destination =
newBitmap(iSize.Width, iSize.Height, PixelFormat.Format1bppIndexed);

destination.SetResolution(hr, hr);

BitmapData destinationData = destination.LockBits(newRectangle(0, 0, destination.Width, destination.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);

imageSize = destinationData.Stride * destinationData.Height;

byte[] destinationBuffer = newbyte[imageSize + 1];

int sourceIndex = 0;

int destinationIndex = 0;

long pixelTotal = 0;

byte destinationValue = 0;

int pixelValue = 128;

int height = iSize.Height;

int width = iSize.Width;

int threshold = 500;

int y = 0;

while (y < height)

{

sourceIndex = y * sourceData.Stride;

destinationIndex = y * destinationData.Stride;

destinationValue = 0;

pixelValue = 128;

int x = 0;

while (x < width)

{

pixelTotal = (
long)sourceBuffer[sourceIndex + 1] + (long)sourceBuffer[sourceIndex + 2] + (long)sourceBuffer[sourceIndex + 3];

if (pixelTotal > threshold)

{

destinationValue += (
byte)pixelValue;

}

if (pixelValue == 1)

{

destinationBuffer[destinationIndex] = destinationValue;

System.
Math.Min(System.Threading.Interlocked.Increment(ref destinationIndex), destinationIndex - 1);

destinationValue = 0;

pixelValue = 128;

}

else

{

pixelValue >>= 1;

}

sourceIndex += 4;

System.
Math.Min(System.Threading.Interlocked.Increment(ref x), x - 1);

}

if (!(pixelValue == 128))

{

destinationBuffer[destinationIndex] = destinationValue;

}

System.
Math.Min(System.Threading.Interlocked.Increment(ref y), y - 1);

}

Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);

destination.UnlockBits(destinationData);

sourceBuffer =
null;

destinationBuffer =
null;

sourceData =
null;

destinationData =
null;

GC.Collect(2);

GC.WaitForPendingFinalizers();

}


Compression should be CCITT3 or 4. else it will produce GDI+ Error.

Have a nice day

 
Last edited:

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top