Skip to content

Commit

Permalink
Zip and resize pass
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Murphy committed Dec 14, 2009
1 parent eac86e6 commit 65ca345
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 54 deletions.
27 changes: 19 additions & 8 deletions ImageUploader/Controller.cs
Expand Up @@ -10,6 +10,7 @@
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
using Path = System.IO.Path;

Expand All @@ -19,7 +20,9 @@ public class Controller
{
public IImageResizer ImageResizer { get; set; }
public IZipper Zipper { get; set; }


private byte[] buffer = new byte[4096];

//for each image on the filesystem pipe through all the streams up to the server

//Resize and produce all the images through the resizer and into memory streams
Expand All @@ -28,28 +31,36 @@ public class Controller

//Pass the Zipper out put stream into teh request stream.

public void ResizeAndZipToStream(Stream responseStream, params string[] filePaths)
public void ResizeAndZipToStream(Stream outputStream, params string[] filePaths)
{
var streams = new List<StreamHolder>();
MemoryStream ms;
foreach (var path in filePaths)
{
using (var fs = File.OpenRead(path))
var fs = File.OpenRead(path);
{
ms = new MemoryStream();
StreamUtils.Copy(fs, ms, buffer);

string fileName = Path.GetFileName(path);
string ext = Path.GetExtension(path);
string prefix = Path.GetFileNameWithoutExtension(path);

var streamHolder = new StreamHolder(fs, fileName);
var streamHolder = new StreamHolder(ms, fileName);

var sizes = new int[100, 300, 500];
var sizes = new int[] { 100, 300, 500 };
foreach (int size in sizes)
{
streams.Add(ImageResizer.ResizeStream(fs, prefix + "_" + size.ToString() + ext, size));

ms.Seek(0, SeekOrigin.Begin);
streams.Add(ImageResizer.ResizeStream(ms, prefix + "_" + size.ToString() + ext, size));
}
Zipper.CreateZip(responseStream, streams.ToArray());



}
}
Zipper.CreateZip(outputStream, streams.ToArray());
}

}
}
84 changes: 40 additions & 44 deletions ImageUploader/Resizer.cs
Expand Up @@ -13,61 +13,57 @@ public class JpgImageResizer : IImageResizer

public StreamHolder ResizeStream(Stream inputStream, string name, int maxWidth, int maxHeight)
{
using (inputStream)
{
// Decode
DecodedJpeg jpegIn = new JpegDecoder(inputStream).Decode();

if (!ImageResizer.ResizeNeeded(jpegIn.Image, maxWidth))
{
return new StreamHolder(inputStream, name);
}
else
{
// Resize
DecodedJpeg jpegOut = new DecodedJpeg(
new ImageResizer(jpegIn.Image)
.Resize(maxWidth, maxHeight, ResamplingFilters.NearestNeighbor),
jpegIn.MetaHeaders); // Retain EXIF details
// Decode
DecodedJpeg jpegIn = new JpegDecoder(inputStream).Decode();

// Encode
var outputStream = new MemoryStream();
new JpegEncoder(jpegOut, 90, outputStream).Encode();
// Display
outputStream.Seek(0, SeekOrigin.Begin);
return new StreamHolder(outputStream, name);
}
if (!ImageResizer.ResizeNeeded(jpegIn.Image, maxWidth))
{
return new StreamHolder(inputStream, name);
}
else
{
// Resize
DecodedJpeg jpegOut = new DecodedJpeg(
new ImageResizer(jpegIn.Image)
.Resize(maxWidth, maxHeight, ResamplingFilters.NearestNeighbor),
jpegIn.MetaHeaders); // Retain EXIF details

// Encode
var outputStream = new MemoryStream();
new JpegEncoder(jpegOut, 90, outputStream).Encode();
// Display
outputStream.Seek(0, SeekOrigin.Begin);
return new StreamHolder(outputStream, name);
}


}

public StreamHolder ResizeStream(Stream inputStream, string name, int maxWidth)
{
using (inputStream)
{
// Decode
DecodedJpeg jpegIn = new JpegDecoder(inputStream).Decode();

if (!ImageResizer.ResizeNeeded(jpegIn.Image, maxWidth))
{
return new StreamHolder(inputStream, name);
}
else
{
// Resize
DecodedJpeg jpegOut = new DecodedJpeg(
new ImageResizer(jpegIn.Image)
.Resize(maxWidth, ResamplingFilters.NearestNeighbor),
jpegIn.MetaHeaders); // Retain EXIF details
// Decode
DecodedJpeg jpegIn = new JpegDecoder(inputStream).Decode();

// Encode
var outputStream = new MemoryStream();
new JpegEncoder(jpegOut, 90, outputStream).Encode();
// Display
outputStream.Seek(0, SeekOrigin.Begin);
return new StreamHolder(outputStream, name);
}
if (!ImageResizer.ResizeNeeded(jpegIn.Image, maxWidth))
{
return new StreamHolder(inputStream, name);
}
else
{
// Resize
DecodedJpeg jpegOut = new DecodedJpeg(
new ImageResizer(jpegIn.Image)
.Resize(maxWidth, ResamplingFilters.NearestNeighbor),
jpegIn.MetaHeaders); // Retain EXIF details

// Encode
var outputStream = new MemoryStream();
new JpegEncoder(jpegOut, 90, outputStream).Encode();
// Display
outputStream.Seek(0, SeekOrigin.Begin);
return new StreamHolder(outputStream, name);
}
}
}
Expand Down
14 changes: 12 additions & 2 deletions ImageUploaderTest1/ZipperTest.cs
Expand Up @@ -28,7 +28,7 @@ public void Setup()
[TearDown]
public void TearDown()
{
Cleanup();
Cleanup();
}

private void Cleanup()
Expand All @@ -52,6 +52,17 @@ public void CanResizeImageAsStream()
}
}

[Test]
public void CanResizeAndZipToStream()
{
Controller controller = new Controller();
controller.ImageResizer = new JpgImageResizer();
controller.Zipper = new Zipper();
controller.ResizeAndZipToStream(File.Create(BasePath + zipName), Directory.GetFiles(BasePath, "*.jpg"));
Assert.IsTrue(File.Exists(BasePath + zipName), "Archive was not created");
}



[Test]
public void DoesSharpZipLibWorks()
Expand Down Expand Up @@ -99,7 +110,6 @@ public void DoesSharpZipLibWorks()
[Test]
public void CanZipFromStream()
{

var paths = Directory.GetFiles(BasePath);
var zipper = new Zipper();

Expand Down
14 changes: 14 additions & 0 deletions README
@@ -0,0 +1,14 @@
This project isn't complete yet. I could use some assistance on the Silverlight end.

Currently the project resizes and zips all with code that is safe for silverlight assemblies.

Ultimately I would like to have a very simple UI with a processing gif (during the resize and zip phase).

Then a mac like progress bar during the upload.

Their should be two buttons one with "Browse files" and one with "Upload files".
I considered the ability to do this all asynch but then doing the single progress bar becomes a battle so I dismissed it.

I think it will make up for non-asynch with the single post and the good UI.


0 comments on commit 65ca345

Please sign in to comment.