The below code is used to merge multipage tiff with single page tiffs.
private void CreatThumbnail(Image thumbNailImg, int iPagesCount)
{
try
{
//TRK
//PictureBox[] picBoxArray = new PictureBox[iPagesCount];
picBoxArray = new PictureBox[iPagesCount];
PictureBox picBox = null;
pnlThumbnail.Controls.Clear();
int iWidth = 300;
int iHeight = 300;
if (!rbShowPageByPage.Checked && !rbShowBoth.Checked)
{
//TRK - 01
iWidth = 308;
iHeight = 550;
pnlThumbnail.Size = new Size(966, 560);
//iWidth = 500;
//iHeight = 550;
//pnlThumbnail.Size = new Size(966, 560);
}
else
{
pnlThumbnail.Location = new Point(16, 110);
pnlThumbnail.Size = new Size(966, 131);
}
int iThumbCurrPage = 0;
for (; iThumbCurrPage < iPagesCount; iThumbCurrPage++)
{
//TRK
picBox = new PictureBox();
thumbNailImg.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, iThumbCurrPage);
using (Image myBmp = new Bitmap(thumbNailImg, iWidth, iHeight))
{
MemoryStream memoryStream = new MemoryStream();
myBmp.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Tiff);
picBox.Image = Image.FromStream(memoryStream); // showing the page in the pictureBox1
myBmp.Dispose();
if (memoryStream != null)
{
memoryStream.Close();
memoryStream.Dispose();
}
GC.Collect();
}
picBox.Size = picBox.Image.Size;
picBox.Location = new Point(1 + (iThumbCurrPage * (iWidth + 10)), 1);
picBoxArray[iThumbCurrPage] = picBox;
picBoxArray[iThumbCurrPage].Name = Convert.ToString(iThumbCurrPage);
toolTipForControls.SetToolTip(picBoxArray[iThumbCurrPage], MessagesAndToolTips.ThumNailClick);
picBoxArray[iThumbCurrPage].Click += new System.EventHandler(this.ThumbNailPictureBox_Click);
pnlThumbnail.Controls.Add(picBoxArray[iThumbCurrPage]);
if (iThumbCurrPage == 0)
objCommonDeclarations.ShowMessage("Loading Page " + Convert.ToString(iThumbCurrPage + 1) + " Of " + Convert.ToString(iPagesCount), "INFO", lblShowMessage);
else
objCommonDeclarations.ShowMessage("Loading Next Page " + Convert.ToString(iThumbCurrPage + 1) + " Of " + Convert.ToString(iPagesCount), "INFO", lblShowMessage);
Application.DoEvents();
GC.Collect();
}
objCommonDeclarations.ShowMessage("Loading Last " + Convert.ToString(iThumbCurrPage) + " Of " + Convert.ToString(iPagesCount), "INFO", lblShowMessage);
Application.DoEvents();
objCommonDeclarations.ShowMessage(string.Empty, "INFO", lblShowMessage);
Application.DoEvents();
}
catch (Exception ex)
{
objCommonDeclarations.ShowMessage(ex.Message.ToString(), "ERROR", lblShowMessage);
objCommonDeclarations.WriteLog(ex.Message.ToString(), false, false);
}
}
private void SwapImages()
{
try
{
int swapPage = Convert.ToInt32(txtPageNumber.Text.Trim()) - 1;
//Open file in read only mode
using (FileStream fs = new FileStream(@lblFile.Text.Trim(), FileMode.Open, FileAccess.Read))
{
string _sDestinatinPath = Path.Combine(CommonDeclarations.sDestinationPath, Path.GetFileName(@lblFile.Text.Trim()));
if (swapPage == 0)
{
using (Image bmp1 = Image.FromStream(fs))//TRK
{
bmp1.Save(_sDestinatinPath, ImageFormat.Tiff);
fs.Dispose();
bmp1.Dispose();
GC.Collect();
}
return;
//background
//return string.Empty;
}
ImageCodecInfo imageCodecInfo = GetEncoderInfo("image/tiff");
//Image bmp = Image.FromStream(fs);
using (Image bmp = Image.FromStream(fs))//TRK
{
//Bitmap bmp = new Bitmap(fs);
int frameCount = bmp.GetFrameCount(FrameDimension.Page);
bmp.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, swapPage);
//Image newTiff = new Bitmap(bmp, bmp.Width, bmp.Height);
//Image newTiff = Converter.ConvertToBitonal(new Bitmap(bmp, bmp.Width, bmp.Height));
using (Image newTiff = Converter.ConvertToBitonal(new Bitmap(bmp, bmp.Width, bmp.Height)))
{
EncoderParameters SaveEncoderParameters = new EncoderParameters(2);
System.Drawing.Imaging.Encoder SaveEncoder = System.Drawing.Imaging.Encoder.SaveFlag;
EncoderParameter CompressEncodeParam = new EncoderParameter(SaveEncoder, (long)(EncoderValue.MultiFrame));
SaveEncoderParameters.Param[0] = CompressEncodeParam;
SaveEncoder = System.Drawing.Imaging.Encoder.Compression;
CompressEncodeParam = new EncoderParameter(SaveEncoder, (long)(EncoderValue.CompressionCCITT4));
SaveEncoderParameters.Param[1] = CompressEncodeParam;
System.Drawing.Imaging.Encoder AddEncoder = System.Drawing.Imaging.Encoder.SaveFlag;
EncoderParameter AddEncodeParam = new EncoderParameter(AddEncoder, (long)EncoderValue.FrameDimensionPage);
System.Drawing.Imaging.Encoder AddCompressionEncoder = System.Drawing.Imaging.Encoder.Compression;
EncoderParameter AddCompressionEncodeParam = new EncoderParameter(AddCompressionEncoder, (long)EncoderValue.CompressionCCITT4);
EncoderParameters AddEncoderParams = new EncoderParameters(2);
AddEncoderParams.Param[0] = AddEncodeParam;
AddEncoderParams.Param[1] = AddCompressionEncodeParam;
ArrayList swap = new ArrayList();
for (int i = 0; i < frameCount; i++)
{
swap.Add(i);
}
swap.Insert(0, swap[swapPage]);
swap.RemoveAt(swapPage + 1);
int pageCount = 0;
for (; pageCount < frameCount; pageCount++)
{
switch (pageCount)
{
case 0:
newTiff.Save(_sDestinatinPath, imageCodecInfo, SaveEncoderParameters);
break;
default:
bmp.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, Convert.ToInt32(swap[pageCount]));
try
{
// Convert image to bitonal for saving to file
using (Bitmap newPage = Converter.ConvertToBitonal(new Bitmap(bmp, bmp.Width, bmp.Height)))//TRK
{
newTiff.SaveAdd(newPage, AddEncoderParams);
newPage.Dispose();
GC.Collect();
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
//GC.WaitForPendingFinalizers();
}
break;
}
////Background
//objCommonDeclarations.ShowMessage("Reordering Images " + Convert.ToString(pageCount + 1) + " of " + Convert.ToString(frameCount), "INFO", lblShowMessage);
//Application.DoEvents();
GC.Collect();
//GC.WaitForPendingFinalizers();
}
//////Background
//objCommonDeclarations.ShowMessage("Reordering Images " + Convert.ToString(pageCount + 1) + " of " + Convert.ToString(frameCount), "INFO", lblShowMessage);
//Application.DoEvents();
//////Background
//objCommonDeclarations.ShowMessage(string.Empty, "INFO", lblShowMessage);
//Application.DoEvents();
AddEncoderParams.Param[0] = new EncoderParameter(AddEncoder, (long)EncoderValue.Flush);
newTiff.SaveAdd(AddEncoderParams);
newTiff.Dispose();
GC.Collect();
}
bmp.Dispose();
fs.Dispose();
GC.Collect();
}
}
}
catch (Exception ex)
{
objCommonDeclarations.ShowMessage(ex.Message.ToString(), "ERROR", lblShowMessage);
//Background
//return ex.Message.ToString();
objCommonDeclarations.WriteLog(ex.Message.ToString(), false, false);
}
//Background
//return string.Empty;
}
///
/// To Merge the Single Page Tifs in folder to a Multipage Tiff Image
///
/// This denotes Multipage Image Full Path/// This denotes Single Page Tif Image List/// After Merge where need to store the New Merged Tif Filesprivate bool MergeTifImages(String sMultiPageTif, List lstSingleTifs, String sDestinationPath)
{
String SinglePageTif = String.Empty;
bool sflg = true;
try
{
// To Check Destination Path is Exist or Not, if not create the path and folder structure
if (!Directory.Exists(@sDestinationPath)) Directory.CreateDirectory(@sDestinationPath);
//Open file in read only mode
using (FileStream fs = new FileStream(@sMultiPageTif, FileMode.Open, FileAccess.Read))
{
//To Form the Destination Tiff File Name
String _sDestinatinPath = Path.Combine(@sDestinationPath, Path.GetFileName(@sMultiPageTif));
//To Create the Image Codec Info
ImageCodecInfo imageCodecInfo = GetEncoderInfo("image/tiff");
//To Create the New bmp Image from the existing Multipage Tif
//Image bmp = Image.FromStream(fs);
Image newTiff = null;
//To Select the Encoder and Compresstion formates for the Tif Images
EncoderParameters SaveEncoderParameters = new EncoderParameters(2);
System.Drawing.Imaging.Encoder SaveEncoder = System.Drawing.Imaging.Encoder.SaveFlag;
EncoderParameter CompressEncodeParam = new EncoderParameter(SaveEncoder, (long)(EncoderValue.MultiFrame));
SaveEncoderParameters.Param[0] = CompressEncodeParam;
SaveEncoder = System.Drawing.Imaging.Encoder.Compression;
CompressEncodeParam = new EncoderParameter(SaveEncoder, (long)(EncoderValue.CompressionCCITT4));
SaveEncoderParameters.Param[1] = CompressEncodeParam;
System.Drawing.Imaging.Encoder AddEncoder = System.Drawing.Imaging.Encoder.SaveFlag;
EncoderParameter AddEncodeParam = new EncoderParameter(AddEncoder, (long)EncoderValue.FrameDimensionPage);
System.Drawing.Imaging.Encoder AddCompressionEncoder = System.Drawing.Imaging.Encoder.Compression;
EncoderParameter AddCompressionEncodeParam = new EncoderParameter(AddCompressionEncoder, (long)EncoderValue.CompressionCCITT4);
EncoderParameters AddEncoderParams = new EncoderParameters(2);
AddEncoderParams.Param[0] = AddEncodeParam;
AddEncoderParams.Param[1] = AddCompressionEncodeParam;
using (Image bmp = Image.FromStream(fs))
{
//Get the Page Count, i.e Frame Count
int frameCount = bmp.GetFrameCount(FrameDimension.Page);
//To Create Temp New Tiff
newTiff = Converter.ConvertToBitonal(new Bitmap(bmp, bmp.Width, bmp.Height));
// To Save the Multipage Tiff
newTiff.Save(_sDestinatinPath, imageCodecInfo, SaveEncoderParameters);
Application.DoEvents();
//To Update frame by frame to the multipage
int pageCount = 0;
for (; pageCount < frameCount; pageCount++)
{
switch (pageCount)
{
case 0:
newTiff.Save(_sDestinatinPath, imageCodecInfo, SaveEncoderParameters);
break;
default:
bmp.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, pageCount);
// Convert image to bitonal for saving to file
using (Bitmap newPage = Converter.ConvertToBitonal(new Bitmap(bmp, bmp.Width, bmp.Height)))
{
//Bitmap newPage = Converter.ConvertToBitonal(new Bitmap(bmp, bmp.Width, bmp.Height));
newTiff.SaveAdd(newPage, AddEncoderParams);
}
break;
}
Application.DoEvents();
}
}
// To Merage the Single Page Tif Image to Multipage Tif Image form Single Tifs List
foreach (String SingleTif in lstSingleTifs)
{
try
{
CommonDeclarations.WriteLog("Single Page TIF: " + Path.GetFileName(SingleTif), false, false);
using (FileStream fs1 = new FileStream(@SingleTif, FileMode.Open, FileAccess.Read))
{
//To over come Out of memory.
//Image Singlebmp = Image.FromStream(fs1);
using (Image Singlebmp = Image.FromStream(fs1))
{
Application.DoEvents();
int frameCount = Singlebmp.GetFrameCount(FrameDimension.Page);
//To Check the Given Single Page tif is having More than One Frame
if (frameCount > 1)
{
CommonDeclarations.WriteLog("The Selected Single Page TIF Having More Then One Page. Page Count: " + frameCount, false, false);
//This works if Multipage exist
int pageCount = 0;
for (; pageCount < frameCount; pageCount++)
{
Singlebmp.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, pageCount);
// Convert image to bitonal for saving to file
Bitmap SinglePageTiff = Converter.ConvertToBitonal(new Bitmap(Singlebmp, Singlebmp.Width, Singlebmp.Height));
newTiff.SaveAdd(SinglePageTiff, AddEncoderParams);
// break;
}
}
else
{
//This will works while Single Frame of Single Tiff Image
using (Bitmap tempBmp = new Bitmap(Singlebmp, Singlebmp.Width, Singlebmp.Height))
{
using (Bitmap SinglePageTifs = Converter.ConvertToBitonal(tempBmp))
{
//Bitmap SinglePageTifs = Converter.ConvertToBitonal(new Bitmap(Singlebmp, Singlebmp.Width, Singlebmp.Height));
Application.DoEvents();
newTiff.SaveAdd(SinglePageTifs, AddEncoderParams);
SinglePageTifs.Dispose();
GC.Collect();
}
tempBmp.Dispose();
GC.Collect();
}
}
Singlebmp.Dispose();
GC.Collect();
}
fs1.Close();
fs1.Dispose();
GC.Collect();
}
}
catch (Exception ex)
{
CommonDeclarations.WriteLog(ex.Message.ToString(), false, false);
sflg = false;
}
}
//Save the New Tiff and Encode the Tiff Images
AddEncoderParams.Param[0] = new EncoderParameter(AddEncoder, (long)EncoderValue.Flush);
newTiff.SaveAdd(AddEncoderParams);
newTiff.Dispose();
GC.Collect();
}
}
catch (Exception ex)
{
//CommonDeclarations.ShowMessage(ex.Message.ToString(), "ERROR", lblShowMessage);
CommonDeclarations.WriteLog("Some Error in MergeTifImages, Error: " + ex.Message.ToString(), false, false);
sflg = false;
}
return sflg;
}
///
/// To Get the ImageCodecInfo. For Example *.TIF,*.TIFF or *.JPG,*.BMP,*.GIF
///
/// This denotes MimeType. Kind of Imgage to Get the Image Files Type///
private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
try
{
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for (j = 0; j < encoders.Length; ++j)
{
if (encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}
catch (Exception ex)
{
CommonDeclarations.WriteLog("Some Error in ImageCodecInfo,Error:"+ ex.Message.ToString(), false, false);
return null;
}
}
After running the application I looked how much memory the Proces use. Object.Dispose(); doesn't release the memory occuped by the object immediately. It shows constant memory increase when seeing.
After using GC.Collect(); if frees the memory. Afterwares no OutOfMemory Exception thrown.
Here we added each image to a panel(pnlThumbnail)
pnlThumbnail.Controls.Add(picBoxArray[iThumbCurrPage]); This occupies more memory. We have to clear that in the following way.
//Clear the picture box stored in thumbnailArray
if (picBoxArray != null)
{
foreach (PictureBox tempPb in picBoxArray)
{
if (tempPb.Image != null)
{
tempPb.Image.Dispose();
tempPb.Image = null;
GC.Collect();
}
}
picBoxArray = null;
}
for (int clearPictureBox = 0; clearPictureBox < pnlThumbnail.Controls.Count; clearPictureBox++)
{
PictureBox pb = pnlThumbnail.Controls[clearPictureBox] as PictureBox;
pnlThumbnail.Controls.Remove(pb);
if (pb.Image != null)
{
pb.Image.Dispose();
pb.Image = null;
}
}
if (pbShowTiffImage.Image != null)
{
pbShowTiffImage.Image = null;
pbShowTiffImage.Invalidate();
GC.Collect();
}
//The above one is better than this
//foreach (IDisposable control in pnlThumbnail.Controls)
// control.Dispose();
pnlThumbnail.Controls.Clear();
GC.Collect();
REferences
Tracking down managed memory leaks (how to find a GC leak)
IDisposable.Dispose Method
Detecting .NET application memory leaks
memory leak with delegates and workflow foundation
http://msdn.microsoft.com/en-us/magazine/cc163491.aspx
Memory Leak Detection in .NET