207 lines
9.6 KiB
C#
207 lines
9.6 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Drawing.Imaging;
|
|
using System.Text.RegularExpressions;
|
|
using System.Web;
|
|
using umbraco.BusinessLogic;
|
|
using umbraco.IO;
|
|
|
|
namespace umbraco.editorControls.tinymce
|
|
{
|
|
internal class tinyMCEImageHelper
|
|
{
|
|
public static string cleanImages(string html)
|
|
{
|
|
string[] allowedAttributes = UmbracoSettings.ImageAllowedAttributes.ToLower().Split(',');
|
|
string pattern = @"<img [^>]*>";
|
|
MatchCollection tags =
|
|
Regex.Matches(html + " ", pattern, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
|
foreach (Match tag in tags)
|
|
{
|
|
if (tag.Value.ToLower().IndexOf("umbraco_macro") == -1)
|
|
{
|
|
string cleanTag = "<img";
|
|
int orgWidth = 0, orgHeight = 0;
|
|
// gather all attributes
|
|
// TODO: This should be replaced with a general helper method - but for now we'll wanna leave umbraco.dll alone for this patch
|
|
Hashtable ht = new Hashtable();
|
|
MatchCollection m =
|
|
Regex.Matches(tag.Value.Replace(">", " >"),
|
|
"(?<attributeName>\\S*)=\"(?<attributeValue>[^\"]*)\"|(?<attributeName>\\S*)=(?<attributeValue>[^\"|\\s]*)\\s",
|
|
RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
|
foreach (Match attributeSet in m)
|
|
{
|
|
ht.Add(attributeSet.Groups["attributeName"].Value.ToString().ToLower(),
|
|
attributeSet.Groups["attributeValue"].Value.ToString());
|
|
if (attributeSet.Groups["attributeName"].Value.ToString().ToLower() == "width")
|
|
orgWidth = int.Parse(attributeSet.Groups["attributeValue"].Value.ToString());
|
|
else if (attributeSet.Groups["attributeName"].Value.ToString().ToLower() == "height")
|
|
orgHeight = int.Parse(attributeSet.Groups["attributeValue"].Value.ToString());
|
|
}
|
|
|
|
// If rel attribute exists and if it's different from current sizing we should resize the image!
|
|
if (helper.FindAttribute(ht, "rel") != "")
|
|
{
|
|
int newWidth = 0, newHeight = 0;
|
|
|
|
// if size has changed resize image serverside
|
|
string[] newDims = helper.FindAttribute(ht, "rel").Split(",".ToCharArray());
|
|
if (newDims.Length > 0 &&
|
|
(newDims[0] != helper.FindAttribute(ht, "width") ||
|
|
newDims[1] != helper.FindAttribute(ht, "height")))
|
|
{
|
|
try
|
|
{
|
|
cleanTag += doResize(ht, out newWidth, out newHeight);
|
|
}
|
|
catch (Exception err)
|
|
{
|
|
cleanTag += " src=\"" + helper.FindAttribute(ht, "src") + "\"";
|
|
if (helper.FindAttribute(ht, "width") != "")
|
|
{
|
|
cleanTag += " width=\"" + helper.FindAttribute(ht, "width") + "\"";
|
|
cleanTag += " height=\"" + helper.FindAttribute(ht, "height") + "\"";
|
|
}
|
|
Log.Add(LogTypes.Error, User.GetUser(0), -1,
|
|
"Error resizing image in editor: " + err.ToString());
|
|
}
|
|
} else
|
|
{
|
|
cleanTag = StripSrc(cleanTag, ht);
|
|
|
|
if (helper.FindAttribute(ht, "width") != "")
|
|
{
|
|
cleanTag += " width=\"" + helper.FindAttribute(ht, "width") + "\"";
|
|
cleanTag += " height=\"" + helper.FindAttribute(ht, "height") + "\"";
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Add src, width and height properties
|
|
cleanTag = StripSrc(cleanTag, ht);
|
|
|
|
|
|
if (helper.FindAttribute(ht, "width") != "")
|
|
{
|
|
cleanTag += " width=\"" + helper.FindAttribute(ht, "width") + "\"";
|
|
cleanTag += " height=\"" + helper.FindAttribute(ht, "height") + "\"";
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Build image tag
|
|
foreach (string attr in allowedAttributes)
|
|
{
|
|
if (helper.FindAttribute(ht, attr) != "")
|
|
{
|
|
string attrValue = helper.FindAttribute(ht, attr);
|
|
cleanTag += " " + attr + "=\"" + attrValue + "\"";
|
|
}
|
|
}
|
|
|
|
|
|
if (bool.Parse(GlobalSettings.EditXhtmlMode))
|
|
cleanTag += "/";
|
|
cleanTag += ">";
|
|
html = html.Replace(tag.Value, cleanTag);
|
|
}
|
|
}
|
|
|
|
return html;
|
|
}
|
|
|
|
private static string StripSrc(string cleanTag, Hashtable ht)
|
|
{
|
|
string src = helper.FindAttribute(ht, "src");
|
|
// update orgSrc to remove umbraco reference
|
|
if (src.IndexOf("/media/") > -1)
|
|
src = src.Substring(src.IndexOf("/media/"), src.Length - src.IndexOf("/media/"));
|
|
|
|
cleanTag += " src=\"" + src + "\"";
|
|
return cleanTag;
|
|
}
|
|
|
|
private static string doResize(Hashtable attributes, out int finalWidth, out int finalHeight)
|
|
{
|
|
string resizeDim = helper.FindAttribute(attributes, "width") + "," +
|
|
helper.FindAttribute(attributes, "height");
|
|
string[] resizeDimSplit = resizeDim.Split(',');
|
|
string orgSrc = HttpContext.Current.Server.HtmlDecode(helper.FindAttribute(attributes, "src").Replace("%20", " "));
|
|
string[] orgDim = helper.FindAttribute(attributes, "rel").Split(",".ToCharArray());
|
|
float orgWidth = float.Parse(orgDim[0]);
|
|
float orgHeight = float.Parse(orgDim[1]);
|
|
string newSrc = "";
|
|
int newWidth = int.Parse(resizeDimSplit[0]);
|
|
int newHeight = int.Parse(resizeDimSplit[1]);
|
|
|
|
//THIS I DO NOW KNOW HOW TO MAKE WORK WITH A VIRTUAL DIRECTORY...
|
|
|
|
if (orgHeight > 0 && orgWidth > 0 && resizeDim != "" && orgSrc != "")
|
|
{
|
|
// Check dimensions
|
|
if (Math.Abs(orgWidth/newWidth) > Math.Abs(orgHeight/newHeight))
|
|
{
|
|
newHeight = (int) Math.Round((float) newWidth*(orgHeight/orgWidth));
|
|
}
|
|
else
|
|
{
|
|
newWidth = (int) Math.Round((float) newHeight*(orgWidth/orgHeight));
|
|
}
|
|
|
|
// update orgSrc to remove umbraco reference
|
|
if (IOHelper.ResolveUrl(orgSrc).IndexOf( IOHelper.ResolveUrl(SystemDirectories.Media)) > -1)
|
|
orgSrc = orgSrc.Substring( orgSrc.IndexOf("/media/"), orgSrc.Length - orgSrc.IndexOf("/media/") );
|
|
|
|
string ext = orgSrc.Substring(orgSrc.LastIndexOf(".") + 1, orgSrc.Length - orgSrc.LastIndexOf(".") - 1);
|
|
newSrc = orgSrc.Replace("." + ext, "_" + newWidth.ToString() + "x" + newHeight.ToString() + ".jpg");
|
|
|
|
string fullSrc = IOHelper.MapPath(orgSrc);
|
|
string fullSrcNew = IOHelper.MapPath(newSrc);
|
|
|
|
// Load original image
|
|
Image image = Image.FromFile(fullSrc);
|
|
|
|
|
|
// Create new image with best quality settings
|
|
Bitmap bp = new Bitmap(newWidth, newHeight);
|
|
Graphics g = Graphics.FromImage(bp);
|
|
g.SmoothingMode = SmoothingMode.HighQuality;
|
|
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
|
|
|
// Copy the old image to the new and resized
|
|
Rectangle rect = new Rectangle(0, 0, newWidth, newHeight);
|
|
g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
|
|
|
|
// Copy metadata
|
|
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
|
|
ImageCodecInfo codec = null;
|
|
for (int i = 0; i < codecs.Length; i++)
|
|
{
|
|
if (codecs[i].MimeType.Equals("image/jpeg"))
|
|
codec = codecs[i];
|
|
}
|
|
|
|
// Set compresion ratio to 90%
|
|
EncoderParameters ep = new EncoderParameters();
|
|
ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
|
|
|
|
// Save the new image
|
|
bp.Save(fullSrcNew, codec, ep);
|
|
}
|
|
|
|
// return the new width and height
|
|
finalWidth = newWidth;
|
|
finalHeight = newHeight;
|
|
|
|
return
|
|
" src=\"" + newSrc + "\" width=\"" + newWidth.ToString() + "\" height=\"" + newHeight.ToString() +
|
|
"\"";
|
|
}
|
|
}
|
|
} |