hello,
first a little background.
I digitize my old Super8 movies using a flatbed scanner
(for details see http://hosting.aktionspotenzial.de/CineToVidWiki )
I recognized, that I get better results, if I scan the movie strips
upside down (emulsion towards the scanner glass). To do this I must also scan the strips from film end towards film start (backward).
To extract the frames properly (that is: not to get mirrored images and a backwards running film) I have to renumber the files containing the strips and I also have to horizontally flip the images.
Therefore I have written a little program, that can do that for me.
The conversion and image saving method is shown below. This method is called in a loop (from a Forms class providing the GUI for the application), this loop provides the filenames of the image source and the image target.
BUT:
As the images are pretty large ( 4MB in JPEG compression, about 170 MB as a Windows Bitmap) this works only for a few images (but this exactly as intended), and then stops with an OutOfMemory Exception.
The loop code looks like this
for (i = startFileIndex; i <= endFileIndex; i++)
{
errFileName = fileEntries[i];
aFileURLB = stripDirectoryB + fileEntries[i];
aFileURLF = stripDirectoryF + fileEntries[numberOfStrips - i - 1];
aNewImage = new NewImage();
imgIndex = aNewImage.flipAndRenameImage(aFileURLB, aFileURLF, errFileName,i);
........
......
aNewImage = null;
}
As you can see in the provided code below, I have tried several things to free memory in the heap, but without any success.
Has anybody an idea, what to do, to get rid of the OutOfMemory exception. I would appreciate that very much.
---------- this is the code that is called from the loop -----------
---------- in each cycle of the calling loop a new instance of NewImage is created and discarded ( set to NULL ) at the end of the cycle -------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Windows.Media.Imaging;
namespace ReformatStrips
{
public class NewImage
{
public Stream imageStreamSource;
public FileStream imageStreamTarget;
public BitmapSource bitmapSource;
public JpegBitmapDecoder decoder;
public JpegBitmapEncoder encoder;
public NewImage()
{
}
public int flipAndRenameImage(string aFileURLB, string aFileURLF, string errFileName, int fileIndex)
{
try
{
imageStreamSource = new FileStream(aFileURLB, FileMode.Open, FileAccess.Read, FileShare.Read);
decoder = new JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
bitmapSource = decoder.Frames[0];
imageStreamTarget = new FileStream(aFileURLF, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
encoder = new JpegBitmapEncoder();
encoder.FlipHorizontal = true;
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
encoder.Save(imageStreamTarget);
imageStreamTarget.Flush();
imageStreamSource.Close();
imageStreamTarget.Close();
imageStreamSource.Dispose();
imageStreamTarget.Dispose();
bitmapSource = null;
imageStreamSource = null;
imageStreamTarget = null;
decoder = null;
encoder = null;
fileIndex = 0;
GC.WaitForFullGCComplete(1000);
GC.Collect(0, GCCollectionMode.Forced);
}
catch (Exception e)
{
imageStreamTarget.Flush();
imageStreamTarget.Close();
GC.WaitForFullGCComplete(1000);
GC.Collect(0, GCCollectionMode.Forced);
Console.WriteLine(e.ToString());
}
return fileIndex;
}
}
}