I've coded following two methods to combine images that are HTTP POSTed to the server:
// Crops two squares out of two separate images
// And then combines them into single image that's returned as byte[]
private byte[] combineImages(HttpPostedFileBase[] itemPayload)
{
try
{
using (var ms = new MemoryStream())
using (var bitmap = new Bitmap(800, 400, PixelFormat.Format24bppRgb))
using (var img1 = Image.FromStream(itemPayload[0].InputStream))
using (var img2 = Image.FromStream(itemPayload[1].InputStream))
using (var g = Graphics.FromImage(bitmap))
{
RectangleF img1Params = getCropParams(img1);
g.DrawImage(img1, new RectangleF(0, 0, 400, 400), img1Params, GraphicsUnit.Pixel);
RectangleF img2Params = getCropParams(img2);
g.DrawImage(img2, new RectangleF(400, 0, 400, 400), img2Params, GraphicsUnit.Pixel);
var encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
bitmap.Save(ms, ImageCodecInfo.GetImageDecoders().Single(codec => codec.FormatID == ImageFormat.Jpeg.Guid), encoderParameters);
return ms.ToArray();
}
}
catch (Exception ex)
{
return new byte[0];
}
}
private RectangleF getCropParams(Image img)
{
var rect = new RectangleF();
if (img.Width > img.Height)
{
rect.X = (img.Width / 2) - (img.Height / 2);
rect.Width = (img.Width / 2) + (img.Height / 2) - rect.X;
rect.Y = 0;
rect.Height = img.Height;
}
else
{
rect.X = 0;
rect.Width = img.Width;
rect.Y = (img.Height / 2) - (img.Width / 2);
rect.Height = (img.Height / 2) + (img.Width / 2) - rect.Y;
}
return rect;
}
It produces results I expect, but I was curious if my implementation could be improved. I am specifically interested in three things:
- Do you see any potential memory leaks?
- Do you think code will be performing well when it comes to scalability
- Is there a component like ImageResizer that can do this?
return new byte[0]
, I'd have a class-level fieldprivate static readonly byte[] emptyImage = new byte[0]
and then justreturn emptyImage
. You may also want to do similarly with yourencoderParameters
so it isn't created on each call as it seems to be invariant. \$\endgroup\$