Sample images of combined manipulations
Introduction
This library is an evolution of the Simple Image Resizing Library I wrote about in January of 2008. Working with and manipulating images has become much more common, so I developed this library to make that work much quicker and easier.
Background
This library uses a Fluent interface to make the code more readable and terse. The Fluent interface also helps to show the image optimizations that can be chained together. While this library does offer a lot of time-saving and space-saving features - there are a few things that it does not do. For example, you will need to handle validation and naming issues: is the image too big? does another image with the same name exist already? etc.
Using the code
To use the library, you will work with one of three main classes: WebImage
, GenericImage
, and ZipImage
. WebImage
should be used, of course, when working with images uploaded from a website. WebImage
and GenericImage
can both manipulate images directly, while ZipImage
can extract images from a Zip file.
There's probably some more work to be done on this library, so suggestions and recommendations are welcome.
Example 1: Single image, single optimization
In this first example, we'll assume that we've just posted to an ASPX page, and used a FileUpload
control to select an image to upload. This code is placed in the ButtonSubmit_Click
method:
var img = new WebImage(fileUploader);
img.Path = "orig";
var fullImageInfo = img.Save();
var resize1 = img.Resize(300, null).Save("resize", "1_" + img.FileName);
var crop1 = img.Crop(300, 300,
CropAnchorPosition.Center).Save("crop", "1_" + img.FileName);
var rotate1 = img.Rotate(45, Color.White).Save(
"rotate", "1_" + img.FileName);
var scale1 = img.Scale(90).Save("scale", "1_" + img.FileName);
img1.ImageUrl = resize1.OriginalPath;
img2.ImageUrl = crop1.OriginalPath;
img3.ImageUrl = rotate1.OriginalPath;
img4.ImageUrl = scale1.OriginalPath;
Now, we'll go over the example above, line by line. The first line creates a WebImage
using the uploaded file. The constructor extracts the image and information, and returns a populated WebImage
object.
var img = new WebImage(fileUploader);
The next line sets the path to the directory "orig". This is the directory that we want to save the original uploaded file into. Please note that you must adjust the permissions on this directory to allow the .NET process to write to it.
img.Path = "orig";
The next line simply calls the Save method that is available on the WebImage
object. Because we didn't pass in any parameters, this method will save the uploaded image using its existing file name.
var fullImageInfo = img.Save();
The next section starts with some image manipulation.
The first line takes the same WebImage
object, and calls the "Resize
" method, constraining only the width (the first parameter) to 300 pixels. The second parameter is for the maximum height, so passing in null
will not constrain the height at all. The next call saves the image to the "resize" directory, and prepends "1_" to the filename.
Resize result from the included sample project
The second line calls the "Crop
" method, setting the width and height to 300 pixels, and cropping from the center of the image. It is then saved to the "crop" directory, with "1_" prepended to the filename.
Crop result from the included sample project
The third line calls the "Rotate
" method, setting the angle to 45, and setting the resulting background color to white. It is then saved as well using the same convention.
Rotate result from the included sample project
The fourth line calls the "Scale
" method, setting the percentage to 90. This is then also saved using the same convention.
Scale result from the included sample project
var resize1 = img.Resize(300, null).Save("resize", "1_" + img.FileName);
var crop1 = img.Crop(300, 300, CropAnchorPosition.Center).Save(
"crop", "1_" + img.FileName);
var rotate1 = img.Rotate(45, Color.White).Save("rotate", "1_" + img.FileName);
var scale1 = img.Scale(90).Save("scale", "1_" + img.FileName);
The next section sets the ImageUrl
for the image controls. Since each command in the above code block ends with a call to the Save
method, each resulting object contains a PathInfo
object for each image. Using the OriginalPath
property will return the complete path to the saved image. This is an important note: most of the methods available on WebImage
or GenericImage
are Fluent, the Save
method is not.
img1.ImageUrl = resize1.OriginalPath;
img2.ImageUrl = crop1.OriginalPath;
img3.ImageUrl = rotate1.OriginalPath;
img4.ImageUrl = scale1.OriginalPath;
Example 2: Single image, chained manipulation
What if you want to do more than one manipulation on one image? Simple, just call each method in the order that you want the manipulation to take place:
var combo1 = img.Resize(400, 250)
.Crop(200, 200, CropAnchorPosition.Center)
.Save("combo", "1_" + img.FileName);
var combo2 = img.Rotate(45, null)
.Crop(200, 200, CropAnchorPosition.Center)
.Rotate(90, null)
.Crop(100, 100, CropAnchorPosition.Center)
.Save("combo", "2_" + img.FileName);
There's not much more to explain for this example. Because of the Fluent interface, the chaining of the methods makes it readable and easy to understand.
Combined manipulation result from the included sample project
It's also possible to combine multiple manipulations with one line of code:
img.ProcessAndSave(new ImageInfo {MaxResizeWidth = 300, RotateAngle = 90});
In the above example, the ProcessAndSave
method takes the ImageInfo
object as a parameter. This example uses an object initializer to set the maximum resize width and the rotation angle.
Example 3: Single image, multiple manipulations
The example above can be taken further by providing a list of ImageInfo
objects to the ProcessAndSaveMultiple
method. The example below will generate four separate images, each manipulated in the way defined in the ImageInfo
objects.
var gallerySize = new ImageInfo {Path = "gallery", MaxResizeWidth = 600};
var featureSize = new ImageInfo {Path = "feature", MaxResizeHeight = 150};
var thumbnailSize = new ImageInfo {Path = "thumb",
MaxResizeWidth = 100, MaxResizeHeight = 100};
var squareSmall = new ImageInfo
{
Path = "square",
MaxResizeWidth = 75,
MaxResizeHeight = 75,
CropWidth = 50,
CropHeight = 50
};
img.ProcessAndSaveMultiple(new List<imageinfo>
{
gallerySize,
featureSize,
thumbnailSize,
squareSmall
});
Example 4: Extract and optimize images in a Zip file
Also included in this library is a utility to extract images from a zip file. To extract the images from a zip file, simply provide the ZipImage
constructor with the Stream
from the file itself:
var zip = new ZipImage(fileUploader.PostedFile.InputStream);
zip.SaveAllMultiple(new List<imageinfo> {gallerySize, featureSize,
thumbnailSize, squareSmall});
In the first line of the example above, we just provided the ZipImage
constructor with the path to the Zip file. This will load the zip file and extract all of the images from the zip file.
**Note: This functionality requires the SharpZip library.
var zip = new ZipImage(fileUploader.PostedFile.FileName);
The second line uses the technique shown in Example 3 to create and save multiple manipulated images for every image extracted from the zip file.
zip.SaveAllMultiple(new List<imageinfo> {gallerySize,
featureSize, thumbnailSize, squareSmall});
Other features
That's the basics of using the LeftImage library, but there are some other features to be aware of. You may be asking, if you use the techniques shown in examples 3 and 4 to upload and manipulate images, how do you get access to each of the images that were created? Simple, use the SavedImages
property to get a list of images that have been saved. This can be particularly useful if you encounter an error within a transactional procedure:
try
{
var zip = new ZipImage(fileUploader.PostedFile.FileName);
zip.SaveAll();
foreach (var image in zip.SavedImages)
{
var p = new Photo();
p.GalleryID = 11;
p.PathToImage = string.Concat(image.Path, "/", image.FileName);
p.Save();
}
}
catch (Exception ex)
{
WebImage.Delete(zip.SavedImages);
}
The LeftImage library also provides more shortcuts through the use of Extension Methods:
using LeftImage.Extensions;
var isSupported = fileUploader.IsSupportedFormat();
fileUploader.Process(new ImageInfo {Path = "pix", MaxResizeWidth = 300}).Save();
fileUploader.ProcessAndSave(new ImageInfo {Path = "pix", MaxResizeWidth = 300});
fileUploader.Resize(100, null).Save();
fileUploader.Resize(100, null).Crop(50, 50, CropAnchorPosition.Center).Save();
Conclusion
That was a quick look at the library. I hope you find it useful. I hope to update this with more features in the future (Opacity, Watermarking, Text Overlay, etc.), and will post those here when I do.