Implementing async image effect processing for image editor

This commit is contained in:
Jaex 2017-11-17 16:35:59 +03:00
parent 5aefb10de4
commit 7df6f6c4f5
2 changed files with 56 additions and 15 deletions

View file

@ -35,13 +35,19 @@ public abstract class BaseEffectShape : BaseShape
public abstract string OverlayText { get; }
private Image canvasCopy;
private bool isEffectCaching;
private Image cachedEffect;
public abstract void ApplyEffect(Bitmap bmp);
public virtual void OnDraw(Graphics g)
{
if (cachedEffect != null)
if (isEffectCaching)
{
OnDrawOverlay(g, "Processing...");
}
else if (cachedEffect != null)
{
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.DrawImage(cachedEffect, RectangleInsideCanvas);
@ -54,6 +60,11 @@ public virtual void OnDraw(Graphics g)
}
public virtual void OnDrawOverlay(Graphics g)
{
OnDrawOverlay(g, OverlayText);
}
public void OnDrawOverlay(Graphics g, string overlayText)
{
using (Brush brush = new SolidBrush(Color.FromArgb(150, Color.Black)))
{
@ -64,14 +75,13 @@ public virtual void OnDrawOverlay(Graphics g)
using (Font font = new Font("Verdana", 12))
{
string text = OverlayText;
Size textSize = g.MeasureString(text, font).ToSize();
Size textSize = g.MeasureString(overlayText, font).ToSize();
if (Rectangle.Width > textSize.Width && Rectangle.Height > textSize.Height)
{
using (StringFormat sf = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center })
{
g.DrawString(text, font, Brushes.White, Rectangle, sf);
g.DrawString(overlayText, font, Brushes.White, Rectangle, sf);
}
}
}
@ -99,7 +109,7 @@ public override void OnCreated()
public override void OnMoving()
{
Dispose();
ClearCache();
}
public override void OnMoved()
@ -109,7 +119,7 @@ public override void OnMoved()
public override void OnResizing()
{
Dispose();
ClearCache();
}
public override void OnResized()
@ -119,16 +129,32 @@ public override void OnResized()
private void CacheEffect()
{
Dispose();
if (IsInsideCanvas)
if (!isEffectCaching)
{
cachedEffect = Manager.CropImage(RectangleInsideCanvas);
ApplyEffect((Bitmap)cachedEffect);
isEffectCaching = true;
if (canvasCopy == null)
{
canvasCopy = (Image)Manager.Form.Canvas.Clone();
}
TaskEx.Run(() =>
{
ClearCache();
if (IsInsideCanvas)
{
cachedEffect = Manager.CropImage(canvasCopy, RectangleInsideCanvas);
ApplyEffect((Bitmap)cachedEffect);
}
isEffectCaching = false;
});
}
}
public override void Dispose()
private void ClearCache()
{
if (cachedEffect != null)
{
@ -136,5 +162,15 @@ public override void Dispose()
cachedEffect = null;
}
}
public override void Dispose()
{
ClearCache();
if (canvasCopy != null)
{
canvasCopy.Dispose();
}
}
}
}

View file

@ -1332,6 +1332,11 @@ public void CropArea(Rectangle rect)
}
public Image CropImage(Rectangle rect, bool onlyIfSizeDifferent = false)
{
return CropImage(Form.Canvas, rect, onlyIfSizeDifferent);
}
public Image CropImage(Image img, Rectangle rect, bool onlyIfSizeDifferent = false)
{
rect = CaptureHelpers.ScreenToClient(rect);
@ -1340,11 +1345,11 @@ public Image CropImage(Rectangle rect, bool onlyIfSizeDifferent = false)
rect.X -= offset.X;
rect.Y -= offset.Y;
rect.Intersect(new Rectangle(0, 0, Form.Canvas.Width, Form.Canvas.Height));
rect.Intersect(new Rectangle(0, 0, img.Width, img.Height));
if (rect.IsValid() && (!onlyIfSizeDifferent || rect.Size != Form.Canvas.Size))
if (rect.IsValid() && (!onlyIfSizeDifferent || rect.Size != img.Size))
{
return ImageHelpers.CropImage(Form.Canvas, rect);
return ImageHelpers.CropImage(img, rect);
}
return null;