Files
Umbraco-CMS/components/editorControls/tinymce/tinyMCEImageHelper.cs

207 lines
9.6 KiB
C#
Raw Normal View History

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() +
"\"";
}
}
}