I have a custom version of the multi file upload package to allow bulk upload of images. My custom media factory resizes the images when they are uploaded and in the Media BeforeSave event I call the ImageCropper datatype to create crops for the images. This all seems to work OK.
What I also want to do however is resize the image when it is uploaded individually. I have tried adding a resize function to the BeforeSave event but this causes an error "Length cannot be less than zero. Parameter name: length" with image cropper.
I am no looking into whether I need to create a custom upload control. Is there any other way of resizing images upon upload though.
Are you able to attach something to an "AfterSave" - so you'd resize it and resiave and then update parameters on the media node (height, width, filesize).
This is something I have thought about previously as clients invariably upload a HUGE image and then try and apply a crop to it but have to scroll left/right and up/down, etc, etc.
That seems to work, the image is resized however when I update the parameters it isn't reflected on the page until the media details are refreshed. Also the image used by Image Cropper isn't refreshed. It still uses the old version, I assume as this is cached by the brower.
Is it an option to resize the image to a different property? I always resize the image, store it in an extra property (called "resized" with the label datatype) and point the image cropper to the resized image. Here is my code which is used in the BeforeSave event:
//Get the umbracoFile and resized properties.
Property propUmbracoFile = media.getProperty("umbracoFile");
Property propResized = media.getProperty("resized");
try
{
#region Create resized image
if (propResized != null && propUmbracoFile != null && propUmbracoFile.Value != null && !string.IsNullOrEmpty(propUmbracoFile.Value.ToString()))
{
//Get the image path.
string umbracoFile = propUmbracoFile.Value.ToString();
//Remove the first slash from the path.
umbracoFile = umbracoFile.Remove(0, 1);
//Get the server path.
string serverPath = HttpContext.Current.Server.MapPath("~");
//Get some strings needed for building the paths.
string umbracoFilePath = Path.Combine(serverPath, umbracoFile.Replace("/", "\\"));
string fileName = Path.GetFileName(umbracoFile);
string extension = Path.GetExtension(umbracoFile);
string shortFileName = fileName.Replace(extension, string.Empty);
string mediaPath = umbracoFile.Substring(0, umbracoFile.LastIndexOf("/"));
//Resize the image to 800x600 and save it.
string format800x600File = string.Concat(mediaPath, "/", shortFileName, "_resized", extension);
string format800x600Path = Path.Combine(serverPath, format800x600File.Replace("/", "\\"));
if (ResizeRequired(media, 800, 600))
{
//Get the image.
byte[] file = File.ReadAllBytes(umbracoFilePath);
ResizeImage(file, format800x600Path, 800, 600, "HW");
}
else
{
// copy the base file instead
File.Copy(umbracoFilePath, format800x600Path, true);
}
//Store the path inside the propertie.
propResized.Value = string.Concat("/", format800x600File);
}
#endregion
}
catch (Exception ex)
{
//log exception
}
Here are some extra methods used in the code above:
/// <summary>
/// Determine if a resize is required based on teh dimensions of the image. If
/// it's smaller than the given dimensions, a resize is not required.
/// </summary>
/// <param name="media"></param>
/// <param name="maxWidth"></param>
/// <param name="maxHeight"></param>
/// <returns></returns>
private bool ResizeRequired(Media media, int maxWidth, int maxHeight)
{
var width = media.GetPropertyValue("umbracoWidth").ToInt();
var height = media.GetPropertyValue("umbracoHeight").ToInt();
return (width != null && height != null
&& (width > maxWidth || height > maxHeight));
}
/// <summary>
/// Create a thumnail
/// </summary>
/// <param name="originalImage">Byte array of the image. Will be converted into System.Drawing.Image</param>
/// <param name="FilePathToSaveTo">full path to where the thumbnail needs to be saved</param>
/// <param name="width">(maximum) width of the thumbnail</param>
/// <param name="height">(maximum) height of the thumbnail</param>
/// <param name="mode">mode to which to resize the image, possible values:
/// HW; resize both the height and width so it fits inside the 'box' defined tby height and width
/// W; resize it to the width specified by 'width', the height will be resized proportionaly
/// H; resize it to the height specified by 'height', the width will be resized proportionaly
/// Cut; crop it to occupy full 'box' defined by the height and width, all overflowing image data will be cut off
/// </param>
public void ResizeImage(byte[] file, string FilePathToSaveTo, int width, int height, string mode)
{
//Convert the byte array to an image.
MemoryStream ms = new MemoryStream(file);
System.Drawing.Image FullsizeImage = System.Drawing.Image.FromStream(ms);
//Create the thumbnail.
ResizeImage(FullsizeImage, FilePathToSaveTo, width, height, mode);
}
public void ResizeImage(System.Drawing.Image originalImage, string FilePathToSaveTo, int width, int height, string mode)
{
int towidth = width;
int toheight = height;
int x = 0;
int y = 0;
int ow = originalImage.Width;
int oh = originalImage.Height;
switch (mode)
{
case "HW":
if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
{
toheight = (int)((Decimal)originalImage.Height / (Decimal)((Decimal)originalImage.Width / (Decimal)towidth));
towidth = width;
}
else
{
towidth = (int)((Decimal)originalImage.Width / (Decimal)((Decimal)originalImage.Height / (Decimal)toheight));
toheight = height;
}
break;
case "W":
toheight = originalImage.Height * width / originalImage.Width;
break;
case "H":
towidth = originalImage.Width * height / originalImage.Height;
break;
case "Cut":
if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
{
oh = originalImage.Height;
ow = originalImage.Height * towidth / toheight;
y = 0;
x = (originalImage.Width - ow) / 2;
}
else
{
ow = originalImage.Width;
oh = originalImage.Width * height / towidth;
x = 0;
y = (originalImage.Height - oh) / 2;
}
break;
default:
throw new Exception("No valid resize mode was passed");
}
System.Drawing.Imaging.ImageCodecInfo[] icf = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
System.Drawing.Imaging.EncoderParameters encps = new System.Drawing.Imaging.EncoderParameters(1);
encps.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.Clear(System.Drawing.Color.Transparent);
g.DrawImage(originalImage, new System.Drawing.Rectangle(0, 0, towidth, toheight),
new System.Drawing.Rectangle(x, y, ow, oh),
System.Drawing.GraphicsUnit.Pixel);
try
{
bitmap.Save(FilePathToSaveTo, icf[1], encps);
}
catch (System.Exception e)
{
throw e;
}
finally
{
originalImage.Dispose();
bitmap.Dispose();
g.Dispose();
}
}
I'm currently trying to implement your code into my site, but can't seem to get my using statements right. I'm using 6.0.2 and assuming your code was based on an older version. If it's not too much trouble, how would you modify it for 6.0.2 and which namespaces need included.
image resing function all in the image programme. you feel free to resize pictures or photos and images quickly, including jpg, png or gif pictures, Digital Photos and other image formats supported by the .NET Image SDK.
The image does get resized but gets saved in a folder named 'media' in umbraco project. I want to see the image in the Media section of umbraco front end. How can i do it?
Resizing image on upload
I have a custom version of the multi file upload package to allow bulk upload of images. My custom media factory resizes the images when they are uploaded and in the Media BeforeSave event I call the ImageCropper datatype to create crops for the images. This all seems to work OK.
What I also want to do however is resize the image when it is uploaded individually. I have tried adding a resize function to the BeforeSave event but this causes an error "Length cannot be less than zero. Parameter name: length" with image cropper.
I am no looking into whether I need to create a custom upload control. Is there any other way of resizing images upon upload though.
Hi Suzyb
Are you able to attach something to an "AfterSave" - so you'd resize it and resiave and then update parameters on the media node (height, width, filesize).
This is something I have thought about previously as clients invariably upload a HUGE image and then try and apply a crop to it but have to scroll left/right and up/down, etc, etc.
Cheers
Nigel
That seems to work, the image is resized however when I update the parameters it isn't reflected on the page until the media details are refreshed. Also the image used by Image Cropper isn't refreshed. It still uses the old version, I assume as this is cached by the brower.
How can I refresh the media item to fix this.
Is it an option to resize the image to a different property? I always resize the image, store it in an extra property (called "resized" with the label datatype) and point the image cropper to the resized image. Here is my code which is used in the BeforeSave event:
Here are some extra methods used in the code above:
Jeroen
@Jeroen
I'm currently trying to implement your code into my site, but can't seem to get my using statements right. I'm using 6.0.2 and assuming your code was based on an older version. If it's not too much trouble, how would you modify it for 6.0.2 and which namespaces need included.
Thanks!
image resing function all in the image programme. you feel free to resize pictures or photos and images quickly, including jpg, png or gif pictures, Digital Photos and other image formats supported by the .NET Image SDK.
Thanks Jeroen for the code. It did help me.
The image does get resized but gets saved in a folder named 'media' in umbraco project. I want to see the image in the Media section of umbraco front end. How can i do it?
is working on a reply...