Fixed the zoom, it was drawn incorrectly. Also changed the drawing to work with a timer, so the updates are made even if the mouse moves to quick. Added a bitblt method in the GDI32 class.

git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2294 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
RKrom 2012-11-18 11:18:20 +00:00
commit 5a1c5fd0eb
3 changed files with 82 additions and 13 deletions

View file

@ -23,10 +23,10 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing;
using Greenshot.Helpers;
@ -51,6 +51,7 @@ namespace Greenshot.Forms {
private int mX;
private int mY;
private Point mouseMovePos = Point.Empty;
private Point cursorPos = Point.Empty;
private Point cursorPosOnBitmap = Point.Empty;
private CaptureMode captureMode = CaptureMode.None;
@ -59,6 +60,8 @@ namespace Greenshot.Forms {
private bool mouseDown = false;
private Rectangle captureRect = Rectangle.Empty;
private ICapture capture = null;
private Image capturedImage = null;
private Timer timer = null;
private Point previousMousePos = Point.Empty;
private FixMode fixMode = FixMode.None;
@ -101,6 +104,14 @@ namespace Greenshot.Forms {
Application.DoEvents();
}
currentForm = this;
// comment this out if the timer should not be used
timer = new Timer();
// Using 32bppPArgb speeds up the drawing.
capturedImage = ImageHelper.Clone(capture.Image, PixelFormat.Format32bppPArgb);
// comment the clone, uncomment the assignment and the original bitmap is used.
//capturedImage = capture.Image;
// clean up
this.FormClosed += delegate {
@ -125,6 +136,13 @@ namespace Greenshot.Forms {
WindowDetails.RegisterIgnoreHandle(this.Handle);
// Unregister at close
this.FormClosing += delegate {
if (timer != null) {
timer.Stop();
}
// remove the buffer if it was created inside this form
if (capturedImage != capture.Image) {
capturedImage.Dispose();
}
LOG.Debug("Closing captureform");
WindowDetails.UnregisterIgnoreHandle(this.Handle);
};
@ -143,13 +161,21 @@ namespace Greenshot.Forms {
WindowDetails.ToForeground(this.Handle);
this.TopMost = true;
CreateZoom();
if (timer != null) {
timer.Interval = 40;
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
}
private void CreateZoom() {
if (zoomForm == null) {
zoomForm = new ZoomForm(capture);
zoomForm = new ZoomForm(capturedImage);
zoomForm.Show(this);
zoomForm.MouseLocation = cursorPos;
zoomForm.ZoomLocation = cursorPosOnBitmap;
// Fix missing focus issue
WindowDetails.ToForeground(this.Handle);
}
@ -271,13 +297,30 @@ namespace Greenshot.Forms {
}
void OnMouseMove(object sender, MouseEventArgs e) {
Point lastPos = new Point(cursorPos.X, cursorPos.Y);
cursorPos = WindowCapture.GetCursorLocation();
// Make sure the mouse coordinates are fixed, when pressing shift
cursorPos = FixMouseCoordinates(cursorPos);
mouseMovePos = FixMouseCoordinates(WindowCapture.GetCursorLocation());
// If the timer is used, the timer_Tick does the following.
// If the timer is not used, we need to call the update ourselves
if (timer == null) {
updateFrame();
}
}
void timer_Tick(object sender, EventArgs e) {
updateFrame();
}
void updateFrame() {
Point lastPos = cursorPos.Clone();
cursorPos = mouseMovePos.Clone();
if (lastPos.Equals(cursorPos)) {
return;
}
// As the cursorPos is not in Bitmap coordinates, we need to correct.
cursorPosOnBitmap = new Point(cursorPos.X, cursorPos.Y);
cursorPosOnBitmap.Offset(-capture.ScreenBounds.Location.X, -capture.ScreenBounds.Location.Y);
Rectangle lastCaptureRect = new Rectangle(captureRect.Location, captureRect.Size);
WindowDetails lastWindow = selectedCaptureWindow;
bool horizontalMove = false;
@ -390,6 +433,8 @@ namespace Greenshot.Forms {
}
}
}
// Force update "now"
Update();
}
/// <summary>
@ -402,7 +447,8 @@ namespace Greenshot.Forms {
void OnPaint(object sender, PaintEventArgs e) {
Graphics graphics = e.Graphics;
Rectangle clipRectangle = e.ClipRectangle;
graphics.DrawImageUnscaled(capture.Image, Point.Empty);
//graphics.BitBlt((Bitmap)buffer, Point.Empty);
graphics.DrawImageUnscaled(capturedImage, Point.Empty);
// Only draw Cursor if it's (partly) visible
if (capture.Cursor != null && capture.CursorVisible && clipRectangle.IntersectsWith(new Rectangle(capture.CursorLocation, capture.Cursor.Size))) {
graphics.DrawIcon(capture.Cursor, capture.CursorLocation.X, capture.CursorLocation.Y);

View file

@ -32,14 +32,14 @@ namespace Greenshot.Forms {
/// </summary>
public class ZoomForm : FormWithoutActivation {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ZoomForm));
private ICapture captureToZoom = null;
private Image imageToZoom = null;
private Point zoomLocation = Point.Empty;
private const int distanceX = 20;
private const int distanceY = 20;
public ZoomForm(ICapture captureToZoom) {
public ZoomForm(Image imageToZoom) {
InitializeComponent();
this.captureToZoom = captureToZoom;
this.imageToZoom = imageToZoom;
Zoom = 400;
}
@ -103,7 +103,7 @@ namespace Greenshot.Forms {
}
protected override void OnPaint(PaintEventArgs e) {
if (captureToZoom == null || captureToZoom.Image == null) {
if (imageToZoom == null) {
return;
}
Graphics graphics = e.Graphics;
@ -111,7 +111,7 @@ namespace Greenshot.Forms {
graphics.SmoothingMode = SmoothingMode.None;
graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
graphics.CompositingQuality = CompositingQuality.HighSpeed;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.None;
Rectangle clipRectangle = e.ClipRectangle;
float zoom = (float)100 / (float)Zoom;
@ -119,7 +119,7 @@ namespace Greenshot.Forms {
int sourceHeight = (int)(Height * zoom);
Rectangle sourceRectangle = new Rectangle(ZoomLocation.X - (sourceWidth / 2), ZoomLocation.Y - (sourceHeight / 2), sourceWidth, sourceHeight);
Rectangle destinationRectangle = new Rectangle(0, 0, Width, Height);
graphics.DrawImage(captureToZoom.Image, destinationRectangle, sourceRectangle, GraphicsUnit.Pixel);
graphics.DrawImage(imageToZoom, destinationRectangle, sourceRectangle, GraphicsUnit.Pixel);
int pixelThickness = Zoom / 100;
using (Pen pen = new Pen(Color.Black, pixelThickness)) {

View file

@ -40,7 +40,7 @@ namespace GreenshotPlugin.UnmanagedHelpers {
/// <summary>
/// GDI32 Helpers
/// </summary>
public class GDI32 {
public static class GDI32 {
[DllImport("gdi32", SetLastError=true)]
public static extern bool BitBlt(IntPtr hObject,int nXDest,int nYDest, int nWidth,int nHeight,IntPtr hObjectSource, int nXSrc,int nYSrc, CopyPixelOperation dwRop);
[DllImport("gdi32", SetLastError=true)]
@ -61,6 +61,29 @@ namespace GreenshotPlugin.UnmanagedHelpers {
public static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);
[DllImport("gdi32")]
public static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int cx, int cy);
/// <summary>
///
/// </summary>
/// <param name="target"></param>
/// <param name="source"></param>
public static void BitBlt(this Graphics target, Bitmap source, Point location) {
IntPtr hDCSrc = IntPtr.Zero;
IntPtr hDCDest = IntPtr.Zero;
try {
hDCDest = target.GetHdc();
hDCSrc = CreateCompatibleDC(hDCDest);
SelectObject(hDCSrc, source.GetHbitmap());
GDI32.BitBlt(hDCDest, location.X, location.Y, source.Width, source.Height, hDCSrc, 0, 0, CopyPixelOperation.SourceCopy);
} finally {
if (hDCSrc != IntPtr.Zero) {
DeleteDC(hDCSrc);
}
if (hDCDest != IntPtr.Zero) {
target.ReleaseHdc(hDCDest);
}
}
}
}
[StructLayout(LayoutKind.Sequential, Pack = 2)]