0

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

amartin94
  • 505
  • 3
  • 19
  • 35
  • possible duplicate of [Difficulty Saving Image To MemoryStream](http://stackoverflow.com/questions/7629887/difficulty-saving-image-to-memorystream) – TheLethalCoder Aug 27 '15 at 10:25

1 Answers1

1

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
}
Community
  • 1
  • 1
Jaime Mendes
  • 643
  • 3
  • 9
  • getting an "Additional information: Value cannot be null." error on: image.Save(stream, image.RawFormat);. Made sure filepath is valid and file exists.. – amartin94 Aug 27 '15 at 10:43
  • My bad, is related to the format. Instead of RawFormat, use ImageFormat.Jpeg (because you know that is jpeg). Gonna update the answer. Just tested in my side. – Jaime Mendes Aug 27 '15 at 10:53
  • Did the example work for you? For some reason im getting an "Entry closed at '0' before the '5263' bytes specified in the header were written" on the tarOutputStream.CloseEntry(); line – amartin94 Aug 27 '15 at 11:05
  • Wasn't testing the ziplib part. Needed to reset the memorystream's position to 0. – Jaime Mendes Aug 27 '15 at 11:40
  • Perferct - got it working. Sorry man - totally new to streams and whatnot!! – amartin94 Aug 27 '15 at 11:49