377 lines
11 KiB
C#
377 lines
11 KiB
C#
|
|
using System;
|
|
using System.Data;
|
|
using System.Configuration;
|
|
using System.Collections;
|
|
using System.Web;
|
|
using System.Web.Security;
|
|
using System.Web.UI;
|
|
using System.Web.UI.WebControls;
|
|
using System.Web.UI.WebControls.WebParts;
|
|
using System.Web.UI.HtmlControls;
|
|
using System.IO;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using ScrewTurn.Wiki;
|
|
using ScrewTurn.Wiki.PluginFramework;
|
|
using System.Drawing.Imaging;
|
|
|
|
namespace ScrewTurn.Wiki {
|
|
|
|
public partial class ImageEditor : BasePage {
|
|
|
|
private MemoryStream resultMemStream = null;
|
|
private string file = "";
|
|
private string page = "";
|
|
private IFilesStorageProviderV30 provider = null;
|
|
|
|
protected void Page_Load(object sender, EventArgs e) {
|
|
SetProvider();
|
|
SetInputData();
|
|
|
|
string currentUser = SessionFacade.GetCurrentUsername();
|
|
string[] currentGroups = SessionFacade.GetCurrentGroupNames();
|
|
string dir = Tools.GetDirectoryName(file);
|
|
|
|
// Verify permissions
|
|
bool canUpload = AuthChecker.CheckActionForDirectory(provider, dir,
|
|
Actions.ForDirectories.UploadFiles, currentUser, currentGroups);
|
|
bool canDeleteFiles = AuthChecker.CheckActionForDirectory(provider, dir,
|
|
Actions.ForDirectories.DeleteFiles, currentUser, currentGroups);
|
|
|
|
if(!canUpload || !canDeleteFiles) UrlTools.Redirect("AccessDenied.aspx");
|
|
|
|
// Inject the proper stylesheet in page head
|
|
Literal l = new Literal();
|
|
l.Text = Tools.GetIncludes(DetectNamespace());
|
|
Page.Header.Controls.Add(l);
|
|
|
|
ResizeImage();
|
|
}
|
|
|
|
private void SetProvider() {
|
|
string p = Request["Provider"];
|
|
if(string.IsNullOrEmpty(p)) {
|
|
p = Settings.DefaultFilesProvider;
|
|
}
|
|
provider = Collectors.FilesProviderCollector.GetProvider(p);
|
|
}
|
|
|
|
private void SetInputData() {
|
|
page = Request["page"];
|
|
|
|
file = Request["File"];
|
|
if(string.IsNullOrEmpty(file)) {
|
|
Response.Write("No file specified.");
|
|
return;
|
|
}
|
|
file = file.Replace("..", "");
|
|
}
|
|
|
|
private int GetSelectedRotation() {
|
|
if(rdo90CW.Checked) return 90;
|
|
else if(rdo90CCW.Checked) return 270;
|
|
else if(rdo180.Checked) return 180;
|
|
else return 0;
|
|
}
|
|
|
|
private void ResizeImage() {
|
|
SetProvider();
|
|
SetInputData();
|
|
|
|
// Contains the image bytes
|
|
MemoryStream ms = new MemoryStream(1048576);
|
|
|
|
// Load from provider
|
|
if(string.IsNullOrEmpty(page)) {
|
|
if(!provider.RetrieveFile(file, ms, false)) {
|
|
Response.StatusCode = 404;
|
|
Response.Write("File not found.");
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
PageInfo info = Pages.FindPage(page);
|
|
if(info == null) {
|
|
Response.StatusCode = 404;
|
|
Response.WriteFile("Page not found.");
|
|
return;
|
|
}
|
|
|
|
if(!provider.RetrievePageAttachment(info, file, ms, false)) {
|
|
Response.StatusCode = 404;
|
|
Response.WriteFile("File not found.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Setup new file name and image format
|
|
if(!Page.IsPostBack) {
|
|
string ext = Path.GetExtension(file);
|
|
txtNewName.Text = Path.GetFileNameWithoutExtension(file) + "-2" + ext;
|
|
switch(ext.ToLowerInvariant()) {
|
|
case ".jpg":
|
|
case ".jpeg":
|
|
rdoPng.Checked = false;
|
|
rdoJpegHigh.Checked = true;
|
|
rdoJpegMedium.Checked = false;
|
|
break;
|
|
default:
|
|
rdoPng.Checked = true;
|
|
rdoJpegHigh.Checked = false;
|
|
rdoJpegMedium.Checked = false;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
ms.Seek(0, SeekOrigin.Begin);
|
|
|
|
// Load the source image
|
|
System.Drawing.Image source = System.Drawing.Image.FromStream(ms);
|
|
|
|
lblCurrentSize.Text = string.Format("{0}x{1}", source.Width, source.Height);
|
|
if(!Page.IsPostBack) {
|
|
txtWidth.Text = source.Width.ToString();
|
|
txtHeight.Text = source.Height.ToString();
|
|
}
|
|
|
|
// Put dimension in script
|
|
lblDimensions.Text = "<script type=\"text/javascript\"><!--\r\nvar width = " +
|
|
source.Width.ToString() +
|
|
";\r\nvar height = " + source.Height.ToString() +
|
|
";\r\n// -->\r\n</script>";
|
|
|
|
int resultWidth = source.Width;
|
|
int resultHeight = source.Height;
|
|
|
|
if(rdoPercentage.Checked) {
|
|
// Resize by percentage
|
|
int dim = 100;
|
|
if(string.IsNullOrEmpty(txtPercentage.Text)) dim = 100;
|
|
else {
|
|
try {
|
|
dim = int.Parse(txtPercentage.Text);
|
|
}
|
|
catch(FormatException) { }
|
|
}
|
|
|
|
// Possible final preview dimensions
|
|
resultWidth = source.Width * dim / 100;
|
|
resultHeight = source.Height * dim / 100;
|
|
}
|
|
else {
|
|
// Resize by pixel
|
|
if(!string.IsNullOrEmpty(txtWidth.Text) && !string.IsNullOrEmpty(txtHeight.Text)) {
|
|
try {
|
|
resultWidth = int.Parse(txtWidth.Text);
|
|
resultHeight = int.Parse(txtHeight.Text);
|
|
}
|
|
catch(FormatException) { }
|
|
}
|
|
}
|
|
|
|
int rotation = GetSelectedRotation();
|
|
|
|
// Draw preview
|
|
if(resultWidth > 290 || resultHeight > 290) {
|
|
int previewWidth = resultWidth;
|
|
int previewHeight = resultHeight;
|
|
|
|
// Max preview dimension 290x290
|
|
if(resultWidth > resultHeight) {
|
|
previewWidth = 290;
|
|
previewHeight = (int)((float)290 / (float)resultWidth * (float)resultHeight);
|
|
lblScale.Text = string.Format("{0:N0}", (float)290 / (float)resultWidth * 100);
|
|
}
|
|
else {
|
|
previewHeight = 290;
|
|
previewWidth = (int)((float)290 / (float)resultHeight * (float)resultWidth);
|
|
lblScale.Text = string.Format("{0:N0}", (float)290 / (float)resultHeight * 100);
|
|
}
|
|
imgPreview.ImageUrl = "Thumb.aspx?File=" + Request["File"] +
|
|
@"&Size=imgeditprev&Width=" + previewWidth + @"&Height=" + previewHeight +
|
|
@"&Page=" + (string.IsNullOrEmpty(page) ? "" : page) +
|
|
(!rdoNoRotation.Checked ? ("&Rot=" + rotation.ToString()) : "");
|
|
}
|
|
else {
|
|
lblScale.Text = "100";
|
|
imgPreview.ImageUrl = "Thumb.aspx?File=" + Request["File"] +
|
|
@"&Size=imgeditprev&Width=" + resultWidth + @"&Height=" + resultHeight +
|
|
@"&Page=" + (string.IsNullOrEmpty(page) ? "" : page) +
|
|
(!rdoNoRotation.Checked ? ("&Rot=" + rotation.ToString()) : "");
|
|
}
|
|
|
|
// Destination bitmap
|
|
Bitmap result = new Bitmap(
|
|
rotation != 90 && rotation != 270 ? resultWidth : resultHeight,
|
|
rotation != 90 && rotation != 270 ? resultHeight : resultWidth,
|
|
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
|
|
|
// Get Graphics object for destination bitmap
|
|
Graphics g = Graphics.FromImage(result);
|
|
g.Clear(Color.Transparent);
|
|
|
|
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
|
|
g.SmoothingMode = SmoothingMode.HighQuality;
|
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
|
|
|
|
g.TranslateTransform(result.Width / 2, result.Height / 2);
|
|
g.RotateTransform(rotation);
|
|
g.TranslateTransform(-result.Width / 2, -result.Height / 2);
|
|
|
|
// Draw bitmap
|
|
g.DrawImage(source, GetImageRectangle(result.Width, result.Height,
|
|
rotation != 90 && rotation != 270 ? source.Width : source.Height,
|
|
rotation != 90 && rotation != 270 ? source.Height : source.Width,
|
|
rotation == 90 || rotation == 270));
|
|
|
|
// Prepare encoder parameters
|
|
string format = GetCurrentFormat();
|
|
resultMemStream = new MemoryStream(1048576);
|
|
|
|
// Only JPEG and PNG images are editable
|
|
if(format == "image/jpeg") {
|
|
EncoderParameters encoderParams = new EncoderParameters(1);
|
|
encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, rdoJpegHigh.Checked ? 100L : 60L);
|
|
|
|
result.Save(resultMemStream, GetEncoderInfo(format), encoderParams);
|
|
}
|
|
else {
|
|
result.Save(resultMemStream, ImageFormat.Png);
|
|
}
|
|
|
|
resultMemStream.Seek(0, SeekOrigin.Begin);
|
|
|
|
// Dispose of source and result bitmaps
|
|
source.Dispose();
|
|
g.Dispose();
|
|
result.Dispose();
|
|
}
|
|
|
|
private static ImageCodecInfo GetEncoderInfo(string mimeType) {
|
|
int j;
|
|
ImageCodecInfo[] encoders;
|
|
encoders = ImageCodecInfo.GetImageEncoders();
|
|
for(j = 0; j < encoders.Length; ++j) {
|
|
if(encoders[j].MimeType == mimeType)
|
|
return encoders[j];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private string GetCurrentFormat() {
|
|
if(chkNewName.Checked) {
|
|
if(rdoPng.Checked) return "image/png";
|
|
else return "image/jpeg";
|
|
}
|
|
else {
|
|
switch(Path.GetExtension(file).ToLowerInvariant()) {
|
|
case ".jpg":
|
|
case ".jpeg":
|
|
return "image/jpeg";
|
|
default:
|
|
return "image/png";
|
|
}
|
|
}
|
|
}
|
|
|
|
private Rectangle GetImageRectangle(int targetW, int targetH, int w, int h, bool swapped) {
|
|
if(w == h) {
|
|
// Square
|
|
return new Rectangle(0, 0, targetW, targetH);
|
|
}
|
|
else if(w > h) {
|
|
// Landscape
|
|
float scale = (float)targetW / (float)w;
|
|
if(targetW > w) scale = 1;
|
|
int width = (int)(w * scale);
|
|
int height = (int)(h * scale);
|
|
|
|
if(swapped) {
|
|
int temp = width;
|
|
width = height;
|
|
height = temp;
|
|
}
|
|
|
|
return new Rectangle((targetW - width) / 2, (targetH - height) / 2, width, height);
|
|
}
|
|
else {
|
|
// Portrait
|
|
float scale = (float)targetH / (float)h;
|
|
if(targetH > h) scale = 1;
|
|
int width = (int)(w * scale);
|
|
int height = (int)(h * scale);
|
|
|
|
if(swapped) {
|
|
int temp = width;
|
|
width = height;
|
|
height = temp;
|
|
}
|
|
|
|
return new Rectangle((targetW - width) / 2, (targetH - height) / 2, width, height);
|
|
}
|
|
}
|
|
|
|
protected void btnPreview_Click(object sender, EventArgs e) {
|
|
//ResizeImage();
|
|
}
|
|
|
|
protected void btnSave_Click(object sender, EventArgs e) {
|
|
ResizeImage();
|
|
bool done = false;
|
|
|
|
string targetName = chkNewName.Checked ? txtNewName.Text : Path.GetFileName(file);
|
|
bool overwrite = !chkNewName.Checked;
|
|
|
|
if(targetName.Length == 0 || Path.GetFileNameWithoutExtension(targetName).Length == 0) {
|
|
lblResult.CssClass = "resulterror";
|
|
lblResult.Text = Properties.Messages.InvalidFileName;
|
|
return;
|
|
}
|
|
|
|
if(!overwrite) {
|
|
// Force extension
|
|
targetName = Path.ChangeExtension(targetName,
|
|
rdoPng.Checked ? "png" : "jpg");
|
|
}
|
|
|
|
if(string.IsNullOrEmpty(page)) {
|
|
string path = (file.LastIndexOf('/') > 0) ? file.Substring(0, file.LastIndexOf('/') + 1) : "";
|
|
done = provider.StoreFile(path + targetName, resultMemStream, overwrite);
|
|
}
|
|
else {
|
|
done = provider.StorePageAttachment(Pages.FindPage(page), targetName, resultMemStream, overwrite);
|
|
}
|
|
|
|
if(done) {
|
|
lblResult.Text = Properties.Messages.FileSaved;
|
|
lblResult.CssClass = "resultok";
|
|
}
|
|
else {
|
|
lblResult.Text = Properties.Messages.CouldNotSaveFile;
|
|
lblResult.CssClass = "resulterror";
|
|
}
|
|
}
|
|
|
|
protected void chkNewName_CheckedChanged(object sender, EventArgs e) {
|
|
txtNewName.Enabled = chkNewName.Checked;
|
|
rdoPng.Enabled = chkNewName.Checked;
|
|
rdoJpegHigh.Enabled = chkNewName.Checked;
|
|
rdoJpegMedium.Enabled = chkNewName.Checked;
|
|
}
|
|
|
|
protected void rdoFormat_CheckedChanged(object sender, EventArgs e) {
|
|
string ext = "";
|
|
if(rdoPng.Checked) {
|
|
ext = ".png";
|
|
}
|
|
else {
|
|
ext = ".jpg";
|
|
}
|
|
txtNewName.Text = Path.ChangeExtension(txtNewName.Text, ext);
|
|
}
|
|
|
|
}
|
|
|
|
}
|