So im using SharpZipLib to recursively browse through my documents and pack up any JPEG image it finds, like this :
foreach (string filename in filenames)
{
string[] file_split = filename.Split('.');
if (file_split[file_split.Count() - 1].Equals("jpg"))
{
// You might replace these 3 lines with your own stream code
ScaleImage scaleImage = new ScaleImage();
FileStream file = new FileStream("path to file", FileMode.Open);
using (Stream inputStream = File.OpenRead(filename))
{
string tarName = filename.Substring(3); // strip off "C:\"
Image tmpImg = scaleImage.scale(tmpImg);
long fileSize = inputStream.Length;
// Create a tar entry named as appropriate. You can set the name to anything,
// but avoid names starting with drive or UNC
TarEntry entry = TarEntry.CreateTarEntry(tarName);
// Must set size, otherwise TarOutputStream will fail when output exceeds.
entry.Size = fileSize;
// Add the entry to the tar stream, before writing the data.
tarOutputStream.PutNextEntry(entry);
// this is copied from TarArchive.WriteEntryCore
byte[] localBuffer = new byte[32 * 1024];
while (true)
{
int numRead = inputStream.Read(localBuffer, 0, localBuffer.Length);
if (numRead <= 0)
{
break;
}
tarOutputStream.Write(localBuffer, 0, numRead);
}
}
tarOutputStream.CloseEntry();
}
}
// Recurse. Delete this if unwanted.
string[] directories = Directory.GetDirectories(sourceDirectory);
foreach (string directory in directories)
{
CreateTarManually(tarOutputStream, directory);
}
To minimize tar size as much as possible - im attempting to resize all images to a specified width x height "on the fly" as the image is being read from the stream. I thought i could load the image from a stream once it's entered the using (Stream inputStream) section and from there use a function found that resizes the image. Something like this:
public Bitmap scale(Image oldImage)
{
double resizeFactor = 1;
if (oldImage.Width > 150 || oldImage.Height > 150)
{
double widthFactor = Convert.ToDouble(oldImage.Width) / 150;
double heightFactor = Convert.ToDouble(oldImage.Height) / 150;
resizeFactor = Math.Max(widthFactor, heightFactor);
}
int width = Convert.ToInt32(oldImage.Width / resizeFactor);
int height = Convert.ToInt32(oldImage.Height / resizeFactor);
Bitmap newImage = new Bitmap(width, height);
Graphics g = Graphics.FromImage(newImage);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(oldImage, 0, 0, newImage.Width, newImage.Height);
return newImage;
}
My question is, how do i pass the stream object to be resized, then add the stream object/resized object to the tar file, and not the original file itself? Effectively i would like all this to be done in memory to save duplicating each file on the disk as its being resized
Gonna use the answer from here.
public Stream ImageToStream(Image image)
{
//Save to stream
MemoryStream stream = new MemoryStream();
image.Save(stream, ImageFormat.Jpeg);
stream.Seek(0, SeekOrigin.Begin); //Need to reset position to 0
return stream;
}
And instead of using the inputstream from the file, use it from the function:
Image oldImage = Image.FromFile(fileName);
Image newImage = scale(oldImage);
Stream inputStream = ImageToStream(newImage);
Bonus suggestion:
If you want to check the file extension, you can use Path.GetExtension(fileName)
like this:
var fileExtension = Path.GetExtension(filename);
if (fileExtension.Equals(".jpg"))
{
//ApplyLogic
}