This commit breaks compiling for a short (!) period, need to sync my work to a different system

This commit is contained in:
Robin Krom 2020-02-25 07:56:45 +01:00
parent 1751880581
commit 684a7615d7
38 changed files with 1845 additions and 1324 deletions

View file

@ -65,14 +65,8 @@ namespace Greenshot.Drawing
/// </summary>
public Guid ID
{
get
{
return _uniqueId;
}
set
{
_uniqueId = value;
}
get => _uniqueId;
set => _uniqueId = value;
}
/// <summary>
@ -82,68 +76,38 @@ namespace Greenshot.Drawing
private PropertyChangedEventHandler _propertyChanged;
public event PropertyChangedEventHandler PropertyChanged
{
add
{
_propertyChanged += value;
}
remove
{
_propertyChanged -= value;
}
add => _propertyChanged += value;
remove => _propertyChanged -= value;
}
[NonSerialized]
private SurfaceElementEventHandler _movingElementChanged;
public event SurfaceElementEventHandler MovingElementChanged
{
add
{
_movingElementChanged += value;
}
remove
{
_movingElementChanged -= value;
}
add => _movingElementChanged += value;
remove => _movingElementChanged -= value;
}
[NonSerialized]
private SurfaceDrawingModeEventHandler _drawingModeChanged;
public event SurfaceDrawingModeEventHandler DrawingModeChanged
{
add
{
_drawingModeChanged += value;
}
remove
{
_drawingModeChanged -= value;
}
add => _drawingModeChanged += value;
remove => _drawingModeChanged -= value;
}
[NonSerialized]
private SurfaceSizeChangeEventHandler _surfaceSizeChanged;
public event SurfaceSizeChangeEventHandler SurfaceSizeChanged
{
add
{
_surfaceSizeChanged += value;
}
remove
{
_surfaceSizeChanged -= value;
}
add => _surfaceSizeChanged += value;
remove => _surfaceSizeChanged -= value;
}
[NonSerialized]
private SurfaceMessageEventHandler _surfaceMessage;
public event SurfaceMessageEventHandler SurfaceMessage
{
add
{
_surfaceMessage += value;
}
remove
{
_surfaceMessage -= value;
}
add => _surfaceMessage += value;
remove => _surfaceMessage -= value;
}
/// <summary>
@ -153,7 +117,7 @@ namespace Greenshot.Drawing
private bool _inUndoRedo;
/// <summary>
/// Make only one surfacemove cycle undoable, see SurfaceMouseMove
/// Make only one surface move cycle undoable, see SurfaceMouseMove
/// </summary>
[NonSerialized]
private bool _isSurfaceMoveMadeUndoable;
@ -179,7 +143,7 @@ namespace Greenshot.Drawing
private DrawingModes _drawingMode = DrawingModes.None;
/// <summary>
/// the keyslocked flag helps with focus issues
/// the keys-locked flag helps with focus issues
/// </summary>
[NonSerialized]
private bool _keysLocked;
@ -265,7 +229,7 @@ namespace Greenshot.Drawing
/// </summary>
public int CounterStart
{
get { return _counterStart; }
get => _counterStart;
set
{
if (_counterStart == value)
@ -330,10 +294,7 @@ namespace Greenshot.Drawing
private Image _image;
public Image Image
{
get
{
return _image;
}
get => _image;
set
{
_image = value;
@ -347,14 +308,8 @@ namespace Greenshot.Drawing
/// </summary>
public FieldAggregator FieldAggregator
{
get
{
return _fieldAggregator;
}
set
{
_fieldAggregator = value;
}
get => _fieldAggregator;
set => _fieldAggregator = value;
}
/// <summary>
@ -381,14 +336,8 @@ namespace Greenshot.Drawing
/// </summary>
public Brush TransparencyBackgroundBrush
{
get
{
return _transparencyBackgroundBrush;
}
set
{
_transparencyBackgroundBrush = value;
}
get => _transparencyBackgroundBrush;
set => _transparencyBackgroundBrush = value;
}
/// <summary>
@ -396,14 +345,8 @@ namespace Greenshot.Drawing
/// </summary>
public bool KeysLocked
{
get
{
return _keysLocked;
}
set
{
_keysLocked = value;
}
get => _keysLocked;
set => _keysLocked = value;
}
/// <summary>
@ -411,14 +354,8 @@ namespace Greenshot.Drawing
/// </summary>
public bool Modified
{
get
{
return _modified;
}
set
{
_modified = value;
}
get => _modified;
set => _modified = value;
}
/// <summary>
@ -426,7 +363,7 @@ namespace Greenshot.Drawing
/// </summary>
public DrawingModes DrawingMode
{
get { return _drawingMode; }
get => _drawingMode;
set
{
_drawingMode = value;
@ -448,14 +385,8 @@ namespace Greenshot.Drawing
/// </summary>
public string LastSaveFullPath
{
get
{
return _lastSaveFullPath;
}
set
{
_lastSaveFullPath = value;
}
get => _lastSaveFullPath;
set => _lastSaveFullPath = value;
}
/// <summary>

View file

@ -39,6 +39,7 @@ using System.Windows.Forms;
using System.Windows.Threading;
using GreenshotPlugin.IniFile;
using GreenshotPlugin.Interfaces;
using GreenshotPlugin.Interfaces.Ocr;
using ZXing;
namespace Greenshot.Forms {
@ -308,7 +309,7 @@ namespace Greenshot.Forms {
TopMost = !TopMost;
break;
case Keys.O:
if (_capture.OcrInformation is null)
if (_capture.CaptureDetails.OcrInformation is null)
{
var ocrProvider = SimpleServiceProvider.Current.GetInstance<IOcrProvider>();
if (ocrProvider is object)
@ -317,36 +318,12 @@ namespace Greenshot.Forms {
Task.Factory.StartNew(async () =>
{
_capture.OcrInformation = await ocrProvider.DoOcrAsync(_capture.Image);
_capture.CaptureDetails.OcrInformation = await ocrProvider.DoOcrAsync(_capture.Image);
Invalidate();
}, CancellationToken.None, TaskCreationOptions.None, uiTaskScheduler);
}
}
break;
case Keys.Q:
// create a barcode reader instance
IBarcodeReader reader = new BarcodeReader();
// detect and decode the barcode inside the bitmap
var result = reader.Decode((Bitmap)_capture.Image);
// do something with the result
if (result != null)
{
Log.InfoFormat("Found QR of type {0} - {1}", result.BarcodeFormat, result.Text);
using var graphics = Graphics.FromImage(_capture.Image);
var boundingBox = BoundingBox(result.ResultPoints.Select(p => new Point((int) p.X, (int) p.Y)));
using var pen = new Pen(Color.BlueViolet, 10);
using var solidBrush = new SolidBrush(Color.Green);
using var solidWhiteBrush = new SolidBrush(Color.White);
using var font = new Font(FontFamily.GenericSerif, 12, FontStyle.Regular);
graphics.FillRectangle(solidWhiteBrush, boundingBox);
graphics.DrawRectangle(pen, boundingBox);
graphics.DrawString(result.Text, font, solidBrush, boundingBox);
}
break;
}
}
@ -762,7 +739,7 @@ namespace Greenshot.Forms {
//graphics.BitBlt((Bitmap)buffer, Point.Empty);
graphics.DrawImageUnscaled(_capture.Image, Point.Empty);
var ocrInfo = _capture.OcrInformation;
var ocrInfo = _capture.CaptureDetails.OcrInformation;
if (ocrInfo != null)
{
using var pen = new Pen(Color.Red);
@ -775,6 +752,25 @@ namespace Greenshot.Forms {
}
}
}
if (_capture.CaptureDetails.QrResult != null)
{
var result = _capture.CaptureDetails.QrResult;
Log.InfoFormat("Found QR of type {0} - {1}", result.BarcodeFormat, result.Text);
var boundingBox = BoundingBox(result.ResultPoints.Select(p => new Point((int)p.X, (int)p.Y)));
using var pen = new Pen(Color.BlueViolet, 10);
using var solidBrush = new SolidBrush(Color.Green);
using var solidWhiteBrush = new SolidBrush(Color.White);
using var font = new Font(FontFamily.GenericSerif, 12, FontStyle.Regular);
graphics.FillRectangle(solidWhiteBrush, boundingBox);
graphics.DrawRectangle(pen, boundingBox);
graphics.DrawString(result.Text, font, solidBrush, boundingBox);
}
// 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

@ -0,0 +1,63 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using GreenshotPlugin.Core;
using GreenshotPlugin.IniFile;
using GreenshotPlugin.Interfaces;
using log4net;
using ZXing;
namespace Greenshot.Processors {
/// <summary>
/// This processor processes a capture to see if there is a QR ode on it
/// </summary>
public class ZXingQrProcessor : AbstractProcessor {
private static readonly ILog LOG = LogManager.GetLogger(typeof(TitleFixProcessor));
private static readonly CoreConfiguration config = IniConfig.GetIniSection<CoreConfiguration>();
public ZXingQrProcessor() {
}
public override string Designation => "QRProcessor";
public override string Description => Designation;
public override bool ProcessCapture(ISurface surface, ICaptureDetails captureDetails) {
// create a barcode reader instance
IBarcodeReader reader = new BarcodeReader();
// detect and decode the barcode inside the bitmap
var result = reader.Decode((Bitmap)surface.Image);
// do something with the result
if (result != null)
{
LOG.InfoFormat("Found QR of type {0} - {1}", result.BarcodeFormat, result.Text);
captureDetails.QrResult = result;
return true;
}
return false;
}
}
}

View file

@ -45,11 +45,7 @@ namespace GreenshotPlugin.Core {
get;
}
public virtual int Priority {
get {
return 10;
}
}
public virtual int Priority => 10;
public void Dispose() {
Dispose(true);
@ -60,11 +56,7 @@ namespace GreenshotPlugin.Core {
//if (disposing) {}
}
public virtual bool isActive {
get {
return true;
}
}
public virtual bool isActive => true;
public abstract bool ProcessCapture(ISurface surface, ICaptureDetails captureDetails);
}

View file

@ -0,0 +1,256 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using GreenshotPlugin.Interfaces;
using GreenshotPlugin.Interfaces.Ocr;
using log4net;
using ZXing;
namespace GreenshotPlugin.Core
{
/// <summary>
/// This class is used to pass an instance of the "Capture" around
/// Having the Bitmap, eventually the Windows Title and cursor all together.
/// </summary>
public class Capture : ICapture {
private static readonly ILog Log = LogManager.GetLogger(typeof(Capture));
private List<ICaptureElement> _elements = new List<ICaptureElement>();
private Rectangle _screenBounds;
/// <summary>
/// Get/Set the Screenbounds
/// </summary>
public Rectangle ScreenBounds {
get {
if (_screenBounds == Rectangle.Empty) {
_screenBounds = WindowCapture.GetScreenBounds();
}
return _screenBounds;
}
set => _screenBounds = value;
}
private Image _image;
/// <summary>
/// Get/Set the Image
/// </summary>
public Image Image {
get => _image;
set {
_image?.Dispose();
_image = value;
if (value != null) {
if (value.PixelFormat.Equals(PixelFormat.Format8bppIndexed) || value.PixelFormat.Equals(PixelFormat.Format1bppIndexed) || value.PixelFormat.Equals(PixelFormat.Format4bppIndexed)) {
Log.Debug("Converting Bitmap to PixelFormat.Format32bppArgb as we don't support: " + value.PixelFormat);
try {
// Default Bitmap PixelFormat is Format32bppArgb
_image = new Bitmap(value);
} finally {
// Always dispose, even when a exception occured
value.Dispose();
}
}
Log.DebugFormat("Image is set with the following specifications: {0} - {1}", _image.Size, _image.PixelFormat);
} else {
Log.Debug("Image is removed.");
}
}
}
public void NullImage() {
_image = null;
}
private Icon _cursor;
/// <summary>
/// Get/Set the image for the Cursor
/// </summary>
public Icon Cursor {
get => _cursor;
set {
_cursor?.Dispose();
_cursor = (Icon)value.Clone();
}
}
/// <summary>
/// The information which OCR brings
/// </summary>
public OcrInformation OcrInformation { get; set; }
/// <summary>
/// Set if the cursor is visible
/// </summary>
public bool CursorVisible { get; set; }
private Point _cursorLocation = Point.Empty;
/// <summary>
/// Get/Set the CursorLocation
/// </summary>
public Point CursorLocation {
get => _cursorLocation;
set => _cursorLocation = value;
}
private Point _location = Point.Empty;
/// <summary>
/// Get/set the Location
/// </summary>
public Point Location {
get => _location;
set => _location = value;
}
private CaptureDetails _captureDetails;
/// <summary>
/// Get/set the CaptureDetails
/// </summary>
public ICaptureDetails CaptureDetails {
get => _captureDetails;
set => _captureDetails = (CaptureDetails)value;
}
/// <summary>
/// Default Constructor
/// </summary>
public Capture() {
_screenBounds = WindowCapture.GetScreenBounds();
_captureDetails = new CaptureDetails();
}
/// <summary>
/// Constructor with Image
/// Note: the supplied bitmap can be disposed immediately or when constructor is called.
/// </summary>
/// <param name="newImage">Image</param>
public Capture(Image newImage) : this() {
Image = newImage;
}
/// <summary>
/// Destructor
/// </summary>
~Capture() {
Dispose(false);
}
/// <summary>
/// The public accessible Dispose
/// Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
/// </summary>
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// This Dispose is called from the Dispose and the Destructor.
/// When disposing==true all non-managed resources should be freed too!
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing) {
if (disposing) {
_image?.Dispose();
_cursor?.Dispose();
}
_image = null;
_cursor = null;
}
/// <summary>
/// Crops the capture to the specified rectangle (with Bitmap coordinates!)
/// </summary>
/// <param name="cropRectangle">Rectangle with bitmap coordinates</param>
public bool Crop(Rectangle cropRectangle) {
Log.Debug("Cropping to: " + cropRectangle);
if (!ImageHelper.Crop(ref _image, ref cropRectangle))
{
return false;
}
_location = cropRectangle.Location;
// Change mouse location according to the cropRectangle (including screenbounds) offset
MoveMouseLocation(-cropRectangle.Location.X, -cropRectangle.Location.Y);
// Move all the elements
// TODO: Enable when the elements are usable again.
// MoveElements(-cropRectangle.Location.X, -cropRectangle.Location.Y);
// Offset the OCR information
CaptureDetails.OcrInformation?.Offset(-cropRectangle.Location.X, -cropRectangle.Location.Y);
var offsetted
CaptureDetails.QrResult.ResultPoints[0];
var resultPoint = new ResultPoint();
// Remove invisible elements
var visibleElements = new List<ICaptureElement>();
foreach(var captureElement in _elements) {
if (captureElement.Bounds.IntersectsWith(cropRectangle)) {
visibleElements.Add(captureElement);
}
}
_elements = visibleElements;
return true;
}
/// <summary>
/// Apply a translate to the mouse location.
/// e.g. needed for crop
/// </summary>
/// <param name="x">x coordinates to move the mouse</param>
/// <param name="y">y coordinates to move the mouse</param>
public void MoveMouseLocation(int x, int y) {
_cursorLocation.Offset(x, y);
}
// TODO: Enable when the elements are usable again.
///// <summary>
///// Apply a translate to the elements
///// e.g. needed for crop
///// </summary>
///// <param name="x">x coordinates to move the elements</param>
///// <param name="y">y coordinates to move the elements</param>
//public void MoveElements(int x, int y) {
// MoveElements(elements, x, y);
//}
//private void MoveElements(List<ICaptureElement> listOfElements, int x, int y) {
// foreach(ICaptureElement childElement in listOfElements) {
// Rectangle bounds = childElement.Bounds;
// bounds.Offset(x, y);
// childElement.Bounds = bounds;
// MoveElements(childElement.Children, x, y);
// }
//}
///// <summary>
///// Add a new element to the capture
///// </summary>
///// <param name="element">CaptureElement</param>
//public void AddElement(ICaptureElement element) {
// int match = elements.IndexOf(element);
// if (match >= 0) {
// if (elements[match].Children.Count < element.Children.Count) {
// elements.RemoveAt(match);
// elements.Add(element);
// }
// } else {
// elements.Add(element);
// }
//}
///// <summary>
///// Returns a list of rectangles which represent object that are on the capture
///// </summary>
//public List<ICaptureElement> Elements {
// get {
// return elements;
// }
// set {
// elements = value;
// }
//}
}
}

View file

@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using GreenshotPlugin.Interfaces;
using GreenshotPlugin.Interfaces.Ocr;
using ZXing;
namespace GreenshotPlugin.Core
{
/// <summary>
/// This Class is used to pass details about the capture around.
/// The time the Capture was taken and the Title of the window (or a region of) that is captured
/// </summary>
public class CaptureDetails : ICaptureDetails {
/// <inheritdoc />
public string Title {
get;
set;
}
/// <inheritdoc />
public string Filename {
get;
set;
}
/// <inheritdoc />
public DateTime DateTime {
get;
set;
}
/// <inheritdoc />
public float DpiX {
get;
set;
}
/// <inheritdoc />
public float DpiY {
get;
set;
}
/// <inheritdoc />
public OcrInformation OcrInformation { get; set; }
/// <inheritdoc />
public Result QrResult { get; set; }
/// <inheritdoc />
public Dictionary<string, string> MetaData { get; } = new Dictionary<string, string>();
/// <inheritdoc />
public void AddMetaData(string key, string value) {
if (MetaData.ContainsKey(key)) {
MetaData[key] = value;
} else {
MetaData.Add(key, value);
}
}
/// <inheritdoc />
public CaptureMode CaptureMode {
get;
set;
}
/// <inheritdoc />
public List<IDestination> CaptureDestinations { get; set; } = new List<IDestination>();
/// <inheritdoc />
public void ClearDestinations() {
CaptureDestinations.Clear();
}
/// <inheritdoc />
public void RemoveDestination(IDestination destination) {
if (CaptureDestinations.Contains(destination)) {
CaptureDestinations.Remove(destination);
}
}
/// <inheritdoc />
public void AddDestination(IDestination captureDestination) {
if (!CaptureDestinations.Contains(captureDestination)) {
CaptureDestinations.Add(captureDestination);
}
}
/// <inheritdoc />
public bool HasDestination(string designation) {
foreach(IDestination destination in CaptureDestinations) {
if (designation.Equals(destination.Designation)) {
return true;
}
}
return false;
}
public CaptureDetails() {
DateTime = DateTime.Now;
}
}
}

View file

@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.Drawing;
using GreenshotPlugin.Interfaces;
namespace GreenshotPlugin.Core
{
/// <summary>
/// A class representing an element in the capture
/// </summary>
public class CaptureElement : ICaptureElement {
public CaptureElement(Rectangle bounds) {
Bounds = bounds;
}
public CaptureElement(string name) {
Name = name;
}
public CaptureElement(string name, Rectangle bounds) {
Name = name;
Bounds = bounds;
}
public List<ICaptureElement> Children { get; set; } = new List<ICaptureElement>();
public string Name {
get;
set;
}
public Rectangle Bounds {
get;
set;
}
// CaptureElements are regarded equal if their bounds are equal. this should be sufficient.
public override bool Equals(object obj) {
if (obj == null || GetType() != obj.GetType())
{
return false;
}
return obj is CaptureElement other && Bounds.Equals(other.Bounds);
}
public override int GetHashCode() {
// TODO: Fix this, this is not right...
return Bounds.GetHashCode();
}
}
}

View file

@ -100,10 +100,10 @@ namespace GreenshotPlugin.Core {
}
/// <summary>
/// Download the uri into a memorystream, without catching exceptions
/// Download the uri into a memory stream, without catching exceptions
/// </summary>
/// <param name="url">Of an image</param>
/// <returns>MemoryStream which is already seeked to 0</returns>
/// <returns>MemoryStream which is already seek-ed to 0</returns>
public static MemoryStream GetAsMemoryStream(string url) {
HttpWebRequest request = CreateWebRequest(url);
using HttpWebResponse response = (HttpWebResponse)request.GetResponse();

View file

@ -33,362 +33,6 @@ using GreenshotPlugin.Interfaces;
using GreenshotPlugin.UnmanagedHelpers.Structs;
namespace GreenshotPlugin.Core {
/// <summary>
/// This Class is used to pass details about the capture around.
/// The time the Capture was taken and the Title of the window (or a region of) that is captured
/// </summary>
public class CaptureDetails : ICaptureDetails {
public string Title {
get;
set;
}
public string Filename {
get;
set;
}
public DateTime DateTime {
get;
set;
}
public float DpiX {
get;
set;
}
public float DpiY {
get;
set;
}
public Dictionary<string, string> MetaData { get; } = new Dictionary<string, string>();
public void AddMetaData(string key, string value) {
if (MetaData.ContainsKey(key)) {
MetaData[key] = value;
} else {
MetaData.Add(key, value);
}
}
public CaptureMode CaptureMode {
get;
set;
}
public List<IDestination> CaptureDestinations { get; set; } = new List<IDestination>();
public void ClearDestinations() {
CaptureDestinations.Clear();
}
public void RemoveDestination(IDestination destination) {
if (CaptureDestinations.Contains(destination)) {
CaptureDestinations.Remove(destination);
}
}
public void AddDestination(IDestination captureDestination) {
if (!CaptureDestinations.Contains(captureDestination)) {
CaptureDestinations.Add(captureDestination);
}
}
public bool HasDestination(string designation) {
foreach(IDestination destination in CaptureDestinations) {
if (designation.Equals(destination.Designation)) {
return true;
}
}
return false;
}
public CaptureDetails() {
DateTime = DateTime.Now;
}
}
/// <summary>
/// This class is used to pass an instance of the "Capture" around
/// Having the Bitmap, eventually the Windows Title and cursor all together.
/// </summary>
public class Capture : ICapture {
private static readonly ILog Log = LogManager.GetLogger(typeof(Capture));
private List<ICaptureElement> _elements = new List<ICaptureElement>();
private Rectangle _screenBounds;
/// <summary>
/// Get/Set the Screenbounds
/// </summary>
public Rectangle ScreenBounds {
get {
if (_screenBounds == Rectangle.Empty) {
_screenBounds = WindowCapture.GetScreenBounds();
}
return _screenBounds;
}
set {_screenBounds = value;}
}
private Image _image;
/// <summary>
/// Get/Set the Image
/// </summary>
public Image Image {
get {return _image;}
set {
_image?.Dispose();
_image = value;
if (value != null) {
if (value.PixelFormat.Equals(PixelFormat.Format8bppIndexed) || value.PixelFormat.Equals(PixelFormat.Format1bppIndexed) || value.PixelFormat.Equals(PixelFormat.Format4bppIndexed)) {
Log.Debug("Converting Bitmap to PixelFormat.Format32bppArgb as we don't support: " + value.PixelFormat);
try {
// Default Bitmap PixelFormat is Format32bppArgb
_image = new Bitmap(value);
} finally {
// Always dispose, even when a exception occured
value.Dispose();
}
}
Log.DebugFormat("Image is set with the following specifications: {0} - {1}", _image.Size, _image.PixelFormat);
} else {
Log.Debug("Image is removed.");
}
}
}
public void NullImage() {
_image = null;
}
private Icon _cursor;
/// <summary>
/// Get/Set the image for the Cursor
/// </summary>
public Icon Cursor {
get {return _cursor;}
set {
_cursor?.Dispose();
_cursor = (Icon)value.Clone();
}
}
/// <summary>
/// The information which OCR brings
/// </summary>
public OcrInformation OcrInformation { get; set; }
/// <summary>
/// Set if the cursor is visible
/// </summary>
public bool CursorVisible { get; set; }
private Point _cursorLocation = Point.Empty;
/// <summary>
/// Get/Set the CursorLocation
/// </summary>
public Point CursorLocation {
get {return _cursorLocation;}
set {_cursorLocation = value;}
}
private Point _location = Point.Empty;
/// <summary>
/// Get/set the Location
/// </summary>
public Point Location {
get {return _location;}
set {_location = value;}
}
private CaptureDetails _captureDetails;
/// <summary>
/// Get/set the CaptureDetails
/// </summary>
public ICaptureDetails CaptureDetails {
get {return _captureDetails;}
set {_captureDetails = (CaptureDetails)value;}
}
/// <summary>
/// Default Constructor
/// </summary>
public Capture() {
_screenBounds = WindowCapture.GetScreenBounds();
_captureDetails = new CaptureDetails();
}
/// <summary>
/// Constructor with Image
/// Note: the supplied bitmap can be disposed immediately or when constructor is called.
/// </summary>
/// <param name="newImage">Image</param>
public Capture(Image newImage) : this() {
Image = newImage;
}
/// <summary>
/// Destructor
/// </summary>
~Capture() {
Dispose(false);
}
/// <summary>
/// The public accessible Dispose
/// Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
/// </summary>
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// This Dispose is called from the Dispose and the Destructor.
/// When disposing==true all non-managed resources should be freed too!
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing) {
if (disposing) {
_image?.Dispose();
_cursor?.Dispose();
}
_image = null;
_cursor = null;
}
/// <summary>
/// Crops the capture to the specified rectangle (with Bitmap coordinates!)
/// </summary>
/// <param name="cropRectangle">Rectangle with bitmap coordinates</param>
public bool Crop(Rectangle cropRectangle) {
Log.Debug("Cropping to: " + cropRectangle);
if (!ImageHelper.Crop(ref _image, ref cropRectangle))
{
return false;
}
_location = cropRectangle.Location;
// Change mouse location according to the cropRegtangle (including screenbounds) offset
MoveMouseLocation(-cropRectangle.Location.X, -cropRectangle.Location.Y);
// Move all the elements
// TODO: Enable when the elements are usable again.
// MoveElements(-cropRectangle.Location.X, -cropRectangle.Location.Y);
// Remove invisible elements
var newElements = new List<ICaptureElement>();
foreach(var captureElement in _elements) {
if (captureElement.Bounds.IntersectsWith(cropRectangle)) {
newElements.Add(captureElement);
}
}
_elements = newElements;
return true;
}
/// <summary>
/// Apply a translate to the mouse location.
/// e.g. needed for crop
/// </summary>
/// <param name="x">x coordinates to move the mouse</param>
/// <param name="y">y coordinates to move the mouse</param>
public void MoveMouseLocation(int x, int y) {
_cursorLocation.Offset(x, y);
}
// TODO: Enable when the elements are usable again.
///// <summary>
///// Apply a translate to the elements
///// e.g. needed for crop
///// </summary>
///// <param name="x">x coordinates to move the elements</param>
///// <param name="y">y coordinates to move the elements</param>
//public void MoveElements(int x, int y) {
// MoveElements(elements, x, y);
//}
//private void MoveElements(List<ICaptureElement> listOfElements, int x, int y) {
// foreach(ICaptureElement childElement in listOfElements) {
// Rectangle bounds = childElement.Bounds;
// bounds.Offset(x, y);
// childElement.Bounds = bounds;
// MoveElements(childElement.Children, x, y);
// }
//}
///// <summary>
///// Add a new element to the capture
///// </summary>
///// <param name="element">CaptureElement</param>
//public void AddElement(ICaptureElement element) {
// int match = elements.IndexOf(element);
// if (match >= 0) {
// if (elements[match].Children.Count < element.Children.Count) {
// elements.RemoveAt(match);
// elements.Add(element);
// }
// } else {
// elements.Add(element);
// }
//}
///// <summary>
///// Returns a list of rectangles which represent object that are on the capture
///// </summary>
//public List<ICaptureElement> Elements {
// get {
// return elements;
// }
// set {
// elements = value;
// }
//}
}
/// <summary>
/// A class representing an element in the capture
/// </summary>
public class CaptureElement : ICaptureElement {
public CaptureElement(Rectangle bounds) {
Bounds = bounds;
}
public CaptureElement(string name) {
Name = name;
}
public CaptureElement(string name, Rectangle bounds) {
Name = name;
Bounds = bounds;
}
public List<ICaptureElement> Children { get; set; } = new List<ICaptureElement>();
public string Name {
get;
set;
}
public Rectangle Bounds {
get;
set;
}
// CaptureElements are regarded equal if their bounds are equal. this should be sufficient.
public override bool Equals(object obj) {
if (obj == null || GetType() != obj.GetType())
{
return false;
}
return obj is CaptureElement other && Bounds.Equals(other.Bounds);
}
public override int GetHashCode() {
// TODO: Fix this, this is not right...
return Bounds.GetHashCode();
}
}
/// <summary>
/// The Window Capture code
/// </summary>
@ -397,7 +41,7 @@ namespace GreenshotPlugin.Core {
private static readonly CoreConfiguration Configuration = IniConfig.GetIniSection<CoreConfiguration>();
/// <summary>
/// Used to cleanup the unmanged resource in the iconInfo for the CaptureCursor method
/// Used to cleanup the unmanaged resource in the iconInfo for the CaptureCursor method
/// </summary>
/// <param name="hObject"></param>
/// <returns></returns>
@ -435,11 +79,11 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Converts locationRelativeToScreenOrigin to be relative to top left corner of all screen bounds, which might
/// be different in multiscreen setups. This implementation
/// be different in multi-screen setups. This implementation
/// can conveniently be used when the cursor location is needed to deal with a fullscreen bitmap.
/// </summary>
/// <param name="locationRelativeToScreenOrigin"></param>
/// <returns></returns>
/// <returns>Point</returns>
public static Point GetLocationRelativeToScreenBounds(Point locationRelativeToScreenOrigin) {
Point ret = locationRelativeToScreenOrigin;
Rectangle bounds = GetScreenBounds();
@ -456,15 +100,16 @@ namespace GreenshotPlugin.Core {
if (capture == null) {
capture = new Capture();
}
CursorInfo cursorInfo = new CursorInfo();
var cursorInfo = new CursorInfo();
cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);
if (User32.GetCursorInfo(out cursorInfo)) {
if (cursorInfo.flags == User32.CURSOR_SHOWING)
{
if (!User32.GetCursorInfo(out cursorInfo)) return capture;
if (cursorInfo.flags != User32.CURSOR_SHOWING) return capture;
using SafeIconHandle safeIcon = User32.CopyIcon(cursorInfo.hCursor);
if (User32.GetIconInfo(safeIcon, out var iconInfo)) {
if (!User32.GetIconInfo(safeIcon, out var iconInfo)) return capture;
Point cursorLocation = User32.GetCursorLocation();
// Allign cursor location to Bitmap coordinates (instead of Screen coordinates)
// Align cursor location to Bitmap coordinates (instead of Screen coordinates)
var x = cursorLocation.X - iconInfo.xHotspot - capture.ScreenBounds.X;
var y = cursorLocation.Y - iconInfo.yHotspot - capture.ScreenBounds.Y;
// Set the location
@ -480,9 +125,6 @@ namespace GreenshotPlugin.Core {
if (iconInfo.hbmColor != IntPtr.Zero) {
DeleteObject(iconInfo.hbmColor);
}
}
}
}
return capture;
}
@ -518,18 +160,18 @@ namespace GreenshotPlugin.Core {
/// <param name="process">Process owning the window</param>
/// <returns>true if it's allowed</returns>
public static bool IsDwmAllowed(Process process) {
if (process != null) {
if (Configuration.NoDWMCaptureForProduct != null && Configuration.NoDWMCaptureForProduct.Count > 0) {
if (process == null) return true;
if (Configuration.NoDWMCaptureForProduct == null ||
Configuration.NoDWMCaptureForProduct.Count <= 0) return true;
try {
string productName = process.MainModule.FileVersionInfo.ProductName;
string productName = process.MainModule?.FileVersionInfo.ProductName;
if (productName != null && Configuration.NoDWMCaptureForProduct.Contains(productName.ToLower())) {
return false;
}
} catch (Exception ex) {
Log.Warn(ex.Message);
}
}
}
return true;
}
@ -539,18 +181,18 @@ namespace GreenshotPlugin.Core {
/// <param name="process">Process owning the window</param>
/// <returns>true if it's allowed</returns>
public static bool IsGdiAllowed(Process process) {
if (process != null) {
if (Configuration.NoGDICaptureForProduct != null && Configuration.NoGDICaptureForProduct.Count > 0) {
if (process == null) return true;
if (Configuration.NoGDICaptureForProduct == null ||
Configuration.NoGDICaptureForProduct.Count <= 0) return true;
try {
string productName = process.MainModule.FileVersionInfo.ProductName;
string productName = process.MainModule?.FileVersionInfo.ProductName;
if (productName != null && Configuration.NoGDICaptureForProduct.Contains(productName.ToLower())) {
return false;
}
} catch (Exception ex) {
Log.Warn(ex.Message);
}
}
}
return true;
}
@ -645,10 +287,10 @@ namespace GreenshotPlugin.Core {
Win32.SetLastError(0);
// create a bitmap we can copy it to, using GetDeviceCaps to get the width/height
using SafeDibSectionHandle safeDibSectionHandle = GDI32.CreateDIBSection(desktopDcHandle, ref bmi, BITMAPINFOHEADER.DIB_RGB_COLORS, out var bits0, IntPtr.Zero, 0);
using SafeDibSectionHandle safeDibSectionHandle = GDI32.CreateDIBSection(desktopDcHandle, ref bmi, BITMAPINFOHEADER.DIB_RGB_COLORS, out _, IntPtr.Zero, 0);
if (safeDibSectionHandle.IsInvalid) {
// Get Exception before the error is lost
Exception exceptionToThrow = CreateCaptureException("CreateDIBSection", captureBounds);
var exceptionToThrow = CreateCaptureException("CreateDIBSection", captureBounds);
exceptionToThrow.Data.Add("hdcDest", safeCompatibleDcHandle.DangerousGetHandle().ToInt32());
exceptionToThrow.Data.Add("hdcSrc", desktopDcHandle.DangerousGetHandle().ToInt32());

View file

@ -15,6 +15,7 @@
<ItemGroup>
<PackageReference Include="log4net" version="2.0.8" />
<PackageReference Include="Svg" Version="3.0.102" />
<PackageReference Include="ZXing.Net" Version="0.16.5" />
<Reference Include="Accessibility" />
<Reference Include="CustomMarshalers" />
</ItemGroup>

View file

@ -1,187 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Drawing;
namespace GreenshotPlugin.Interfaces {
/// <summary>
/// The capture mode for Greenshot
/// </summary>
public enum CaptureMode { None, Region, FullScreen, ActiveWindow, Window, LastRegion, Clipboard, File, IE, Import}; //, Video };
public enum ScreenCaptureMode { Auto, FullScreen, Fixed};
/// <summary>
/// Details for the capture, like the window title and date/time etc.
/// </summary>
public interface ICaptureDetails {
string Filename {
get;
set;
}
string Title {
get;
set;
}
DateTime DateTime {
get;
set;
}
List<IDestination> CaptureDestinations {
get;
set;
}
Dictionary<string, string> MetaData {
get;
}
/// <summary>
/// Helper method to prevent complex code which needs to check every key
/// </summary>
/// <param name="key">The key for the meta-data</param>
/// <param name="value">The value for the meta-data</param>
void AddMetaData(string key, string value);
void ClearDestinations();
void RemoveDestination(IDestination captureDestination);
void AddDestination(IDestination captureDestination);
bool HasDestination(string designation);
CaptureMode CaptureMode {
get;
set;
}
float DpiX {
get;
set;
}
float DpiY {
get;
set;
}
}
public interface ICaptureElement {
List<ICaptureElement> Children {
get;
set;
}
Rectangle Bounds {
get;
set;
}
string Name {
get;
set;
}
}
/// <summary>
/// The interface to the Capture object, so Plugins can use it.
/// </summary>
public interface ICapture : IDisposable {
// The Capture Details
ICaptureDetails CaptureDetails {
get;
set;
}
// The captured Image
Image Image {
get;
set;
}
void NullImage();
Rectangle ScreenBounds {
get;
set;
}
Icon Cursor {
get;
set;
}
// Boolean to specify if the cursor is available
bool CursorVisible {
get;
set;
}
Point CursorLocation {
get;
set;
}
Point Location {
get;
set;
}
/// <summary>
/// Crops the capture to the specified rectangle (with Bitmap coordinates!)
/// </summary>
/// <param name="cropRectangle">Rectangle with bitmap coordinates</param>
bool Crop(Rectangle cropRectangle);
/// <summary>
/// Apply a translate to the mouse location. e.g. needed for crop
/// </summary>
/// <param name="x">x coordinates to move the mouse</param>
/// <param name="y">y coordinates to move the mouse</param>
void MoveMouseLocation(int x, int y);
/// <summary>
/// Store the OCR information for this capture
/// </summary>
OcrInformation OcrInformation { get; set; }
// / TODO: Enable when the elements are usable again.
///// <summary>
///// Apply a translate to the elements e.g. needed for crop
///// </summary>
///// <param name="x">x coordinates to move the elements</param>
///// <param name="y">y coordinates to move the elements</param>
//void MoveElements(int x, int y);
///// <summary>
///// Add a new element to the capture
///// </summary>
///// <param name="element">Rectangle</param>
//void AddElement(ICaptureElement element);
///// <summary>
///// Returns a list of rectangles which represent objects that are "on" the capture
///// </summary>
//List<ICaptureElement> Elements {
// get;
// set;
//}
}
}

View file

@ -0,0 +1,41 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotPlugin.Interfaces
{
/// <summary>
/// The capture mode for Greenshot
/// </summary>
public enum CaptureMode
{
None,
Region,
FullScreen,
ActiveWindow,
Window,
LastRegion,
Clipboard,
File,
IE,
Import
// Video
};
}

View file

@ -0,0 +1,40 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotPlugin.Interfaces
{
public enum DrawingModes
{
None,
Rect,
Ellipse,
Text,
Line,
Arrow,
Crop,
Highlight,
Obfuscate,
Bitmap,
Path,
SpeechBubble,
StepLabel
}
}

View file

@ -1,266 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using GreenshotPlugin.Effects;
using GreenshotPlugin.Interfaces.Drawing;
namespace GreenshotPlugin.Interfaces
{
/// <summary>
/// Alignment Enums for possitioning
/// </summary>
//public enum HorizontalAlignment {LEFT, CENTER, RIGHT};
public enum VerticalAlignment { TOP, CENTER, BOTTOM };
public enum SurfaceMessageTyp
{
FileSaved,
Error,
Info,
UploadedUri
}
public class SurfaceMessageEventArgs : EventArgs
{
public SurfaceMessageTyp MessageType
{
get;
set;
}
public string Message
{
get;
set;
}
public ISurface Surface
{
get;
set;
}
}
public class SurfaceElementEventArgs : EventArgs
{
public IDrawableContainerList Elements
{
get;
set;
}
}
public class SurfaceDrawingModeEventArgs : EventArgs
{
public DrawingModes DrawingMode
{
get;
set;
}
}
public delegate void SurfaceSizeChangeEventHandler(object sender, EventArgs e);
public delegate void SurfaceMessageEventHandler(object sender, SurfaceMessageEventArgs e);
public delegate void SurfaceElementEventHandler(object sender, SurfaceElementEventArgs e);
public delegate void SurfaceDrawingModeEventHandler(object sender, SurfaceDrawingModeEventArgs e);
public enum DrawingModes
{
None,
Rect,
Ellipse,
Text,
Line,
Arrow,
Crop,
Highlight,
Obfuscate,
Bitmap,
Path,
SpeechBubble,
StepLabel
}
/// <summary>
/// The interface to the Surface object, so Plugins can use it.
/// </summary>
public interface ISurface : IDisposable
{
event SurfaceSizeChangeEventHandler SurfaceSizeChanged;
event SurfaceMessageEventHandler SurfaceMessage;
event SurfaceDrawingModeEventHandler DrawingModeChanged;
event SurfaceElementEventHandler MovingElementChanged;
/// <summary>
/// Start valueof the step-labels (counts)
/// </summary>
int CounterStart { get; set; }
/// <summary>
/// Unique ID of the Surface
/// </summary>
Guid ID
{
get;
set;
}
IDrawableContainerList Elements
{
get;
}
/// <summary>
/// Get/Set the image to the Surface
/// get will give the image as is currently visible
/// set will overwrite both the visible image as the underlying image
///
/// important notice:
/// The setter will clone the passed bitmap and dispose it when the Surface is disposed
/// This means that the supplied image needs to be disposed by the calling code (if needed!)
/// </summary>
Image Image
{
get;
set;
}
/// <summary>
/// Get the current Image from the Editor for Exporting (save/upload etc)
/// Don't forget to call image.Dispose() when finished!!!
/// </summary>
/// <returns>Bitmap</returns>
Image GetImageForExport();
/// <summary>
/// Add a TextContainer, at the given location, to the Surface.
/// The TextContainer will be "re"sized to the text size.
/// </summary>
/// <param name="text">String to show</param>
/// <param name="horizontalAlignment">Left, Center, Right</param>
/// <param name="verticalAlignment">TOP, CENTER, BOTTOM</param>
/// <param name="family">FontFamily</param>
/// <param name="size">Font Size in float</param>
/// <param name="italic">bool true if italic</param>
/// <param name="bold">bool true if bold</param>
/// <param name="shadow">bool true if shadow</param>
/// <param name="borderSize">size of border (0 for none)</param>
/// <param name="color">Color of string</param>
/// <param name="fillColor">Color of background (e.g. Color.Transparent)</param>
ITextContainer AddTextContainer(string text, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, FontFamily family, float size, bool italic, bool bold, bool shadow, int borderSize, Color color, Color fillColor);
IImageContainer AddImageContainer(Image image, int x, int y);
ICursorContainer AddCursorContainer(Cursor cursor, int x, int y);
IIconContainer AddIconContainer(Icon icon, int x, int y);
IImageContainer AddImageContainer(string filename, int x, int y);
ICursorContainer AddCursorContainer(string filename, int x, int y);
IIconContainer AddIconContainer(string filename, int x, int y);
long SaveElementsToStream(Stream stream);
void LoadElementsFromStream(Stream stream);
bool HasSelectedElements
{
get;
}
void RemoveSelectedElements();
void CutSelectedElements();
void CopySelectedElements();
void PasteElementFromClipboard();
void DuplicateSelectedElements();
void DeselectElement(IDrawableContainer container, bool generateEvents = true);
void DeselectAllElements();
/// <summary>
/// Add an element to the surface
/// </summary>
/// <param name="elements">IDrawableContainerList</param>
/// <param name="makeUndoable">Should it be placed on the undo stack?</param>
void AddElements(IDrawableContainerList elements, bool makeUndoable = true);
void RemoveElements(IDrawableContainerList elements, bool makeUndoable = true);
void SelectElements(IDrawableContainerList elements);
/// <summary>
/// Add an element to the surface
/// </summary>
/// <param name="element">IDrawableContainer</param>
/// <param name="makeUndoable">Should it be placed on the undo stack?</param>
/// <param name="invalidate">Should it be invalidated (draw)</param>
void AddElement(IDrawableContainer element, bool makeUndoable = true, bool invalidate = true);
/// <summary>
/// Select the supplied container
/// </summary>
/// <param name="container">IDrawableContainer</param>
/// <param name="invalidate">false to skip invalidation</param>
/// <param name="generateEvents">false to skip event generation</param>
void SelectElement(IDrawableContainer container, bool invalidate = true, bool generateEvents = true);
/// <summary>
/// Is the supplied container "on" the surface?
/// </summary>
/// <param name="container"></param>
/// <returns>This returns false if the container is deleted but still in the undo stack</returns>
bool IsOnSurface(IDrawableContainer container);
void Invalidate(Rectangle rectangleToInvalidate);
void Invalidate();
bool Modified
{
get;
set;
}
string LastSaveFullPath
{
get;
set;
}
string UploadUrl
{
get;
set;
}
/// <summary>
/// Remove an element of the elements list
/// </summary>
/// <param name="elementToRemove">Element to remove</param>
/// <param name="makeUndoable">flag specifying if the remove needs to be undoable</param>
/// <param name="invalidate">flag specifying if an surface invalidate needs to be called</param>
/// <param name="generateEvents">flag specifying if the deselect needs to generate an event</param>
void RemoveElement(IDrawableContainer elementToRemove, bool makeUndoable = true, bool invalidate = true, bool generateEvents = true);
void SendMessageEvent(object source, SurfaceMessageTyp messageType, string message);
void ApplyBitmapEffect(IEffect effect);
void RemoveCursor();
bool HasCursor
{
get;
}
ICaptureDetails CaptureDetails
{
get;
set;
}
int Width { get; }
int Height { get; }
void MakeUndoable(IMemento memento, bool allowMerge);
}
}

View file

@ -0,0 +1,105 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Drawing;
namespace GreenshotPlugin.Interfaces
{
/// <summary>
/// The interface to the Capture object, so Plugins can use it.
/// </summary>
public interface ICapture : IDisposable {
/// <summary>
/// The Capture Details
/// </summary>
ICaptureDetails CaptureDetails {
get;
set;
}
/// <summary>
/// The captured Image
/// </summary>
Image Image {
get;
set;
}
/// <summary>
/// Null the image
/// </summary>
void NullImage();
/// <summary>
/// Bounds on the screen from which the capture comes
/// </summary>
Rectangle ScreenBounds {
get;
set;
}
/// <summary>
/// The cursor
/// </summary>
Icon Cursor {
get;
set;
}
/// <summary>
/// Boolean to specify if the cursor is available
/// </summary>
bool CursorVisible {
get;
set;
}
/// <summary>
/// Location of the cursor
/// </summary>
Point CursorLocation {
get;
set;
}
/// <summary>
/// Location of the capture
/// </summary>
Point Location {
get;
set;
}
/// <summary>
/// Crops the capture to the specified rectangle (with Bitmap coordinates!)
/// </summary>
/// <param name="cropRectangle">Rectangle with bitmap coordinates</param>
bool Crop(Rectangle cropRectangle);
/// <summary>
/// Apply a translate to the mouse location. e.g. needed for crop
/// </summary>
/// <param name="x">x coordinates to move the mouse</param>
/// <param name="y">y coordinates to move the mouse</param>
void MoveMouseLocation(int x, int y);
}
}

View file

@ -0,0 +1,109 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using GreenshotPlugin.Interfaces.Ocr;
using ZXing;
namespace GreenshotPlugin.Interfaces {
/// <summary>
/// Details for the capture, like the window title and date/time etc.
/// </summary>
public interface ICaptureDetails {
/// <summary>
/// If the capture comes from a file, this contains the filename
/// </summary>
string Filename {
get;
set;
}
/// <summary>
/// The title of the capture
/// </summary>
string Title {
get;
set;
}
/// <summary>
/// When was the capture taken (or loaded)
/// </summary>
DateTime DateTime {
get;
set;
}
/// <summary>
/// Destinations to where this capture goes or went
/// </summary>
List<IDestination> CaptureDestinations {
get;
set;
}
/// <summary>
/// The meta data of the capture
/// </summary>
Dictionary<string, string> MetaData {
get;
}
/// <summary>
/// Helper method to prevent complex code which needs to check every key
/// </summary>
/// <param name="key">The key for the meta-data</param>
/// <param name="value">The value for the meta-data</param>
void AddMetaData(string key, string value);
void ClearDestinations();
void RemoveDestination(IDestination captureDestination);
void AddDestination(IDestination captureDestination);
bool HasDestination(string designation);
CaptureMode CaptureMode {
get;
set;
}
float DpiX {
get;
set;
}
float DpiY {
get;
set;
}
/// <summary>
/// Store the OCR information for this capture
/// </summary>
OcrInformation OcrInformation { get; set; }
/// <summary>
/// Store the QR information for this capture
/// </summary>
Result QrResult { get; set; }
}
}

View file

@ -0,0 +1,41 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
using System.Drawing;
namespace GreenshotPlugin.Interfaces
{
public interface ICaptureElement {
List<ICaptureElement> Children {
get;
set;
}
Rectangle Bounds {
get;
set;
}
string Name {
get;
set;
}
}
}

View file

@ -1,127 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
using System.Drawing;
using System.Threading.Tasks;
namespace GreenshotPlugin.Interfaces
{
/// <summary>
/// This interface describes something that can do OCR of a bitmap
/// </summary>
public interface IOcrProvider
{
/// <summary>
/// Start the actual OCR
/// </summary>
/// <param name="image">Image</param>
/// <returns>OcrInformation</returns>
Task<OcrInformation> DoOcrAsync(Image image);
/// <summary>
/// Start the actual OCR
/// </summary>
/// <param name="surface">ISurface</param>
/// <returns>OcrInformation</returns>
Task<OcrInformation> DoOcrAsync(ISurface surface);
}
/// <summary>
/// Contains the information about a word
/// </summary>
public class Word
{
/// <summary>
/// The actual text for the word
/// </summary>
public string Text { get; set; }
/// <summary>
/// The location of the word
/// </summary>
public Rectangle Location { get; set; }
}
/// <summary>
/// Describes a line of words
/// </summary>
public class Line
{
private Rectangle? _calculatedBounds;
/// <summary>
/// Constructor will preallocate the number of words
/// </summary>
/// <param name="wordCount">int</param>
public Line(int wordCount)
{
Words = new Word[wordCount];
for (int i = 0; i < wordCount; i++)
{
Words[i] = new Word();
}
}
/// <summary>
/// An array with words
/// </summary>
public Word[] Words { get; }
/// <summary>
/// Calculate the bounds of the words
/// </summary>
/// <returns>Rectangle</returns>
private Rectangle CalculateBounds()
{
if (Words.Length == 0)
{
return Rectangle.Empty;
}
var result = Words[0].Location;
for (var index = 0; index < Words.Length; index++)
{
result = Rectangle.Union(result, Words[index].Location);
}
return result;
}
/// <summary>
/// Return the calculated bounds for the whole line
/// </summary>
public Rectangle CalculatedBounds
{
get { return _calculatedBounds ??= CalculateBounds(); }
}
}
/// <summary>
/// Contains all the information on the OCR result
/// </summary>
public class OcrInformation
{
public string Text { get; set; }
public IList<Line> Lines { get; } = new List<Line>();
}
}

View file

@ -0,0 +1,194 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using GreenshotPlugin.Effects;
using GreenshotPlugin.Interfaces.Drawing;
namespace GreenshotPlugin.Interfaces
{
/// <summary>
/// The interface to the Surface object, so Plugins can use it.
/// </summary>
public interface ISurface : IDisposable
{
event SurfaceSizeChangeEventHandler SurfaceSizeChanged;
event SurfaceMessageEventHandler SurfaceMessage;
event SurfaceDrawingModeEventHandler DrawingModeChanged;
event SurfaceElementEventHandler MovingElementChanged;
/// <summary>
/// Start value of the step-labels (counts)
/// </summary>
int CounterStart { get; set; }
/// <summary>
/// Unique ID of the Surface
/// </summary>
Guid ID
{
get;
set;
}
IDrawableContainerList Elements
{
get;
}
/// <summary>
/// Get/Set the image to the Surface
/// get will give the image as is currently visible
/// set will overwrite both the visible image as the underlying image
///
/// important notice:
/// The setter will clone the passed bitmap and dispose it when the Surface is disposed
/// This means that the supplied image needs to be disposed by the calling code (if needed!)
/// </summary>
Image Image
{
get;
set;
}
/// <summary>
/// Get the current Image from the Editor for Exporting (save/upload etc)
/// Don't forget to call image.Dispose() when finished!!!
/// </summary>
/// <returns>Bitmap</returns>
Image GetImageForExport();
/// <summary>
/// Add a TextContainer, at the given location, to the Surface.
/// The TextContainer will be "re"sized to the text size.
/// </summary>
/// <param name="text">String to show</param>
/// <param name="horizontalAlignment">Left, Center, Right</param>
/// <param name="verticalAlignment">TOP, CENTER, BOTTOM</param>
/// <param name="family">FontFamily</param>
/// <param name="size">Font Size in float</param>
/// <param name="italic">bool true if italic</param>
/// <param name="bold">bool true if bold</param>
/// <param name="shadow">bool true if shadow</param>
/// <param name="borderSize">size of border (0 for none)</param>
/// <param name="color">Color of string</param>
/// <param name="fillColor">Color of background (e.g. Color.Transparent)</param>
ITextContainer AddTextContainer(string text, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, FontFamily family, float size, bool italic, bool bold, bool shadow, int borderSize, Color color, Color fillColor);
IImageContainer AddImageContainer(Image image, int x, int y);
ICursorContainer AddCursorContainer(Cursor cursor, int x, int y);
IIconContainer AddIconContainer(Icon icon, int x, int y);
IImageContainer AddImageContainer(string filename, int x, int y);
ICursorContainer AddCursorContainer(string filename, int x, int y);
IIconContainer AddIconContainer(string filename, int x, int y);
long SaveElementsToStream(Stream stream);
void LoadElementsFromStream(Stream stream);
bool HasSelectedElements
{
get;
}
void RemoveSelectedElements();
void CutSelectedElements();
void CopySelectedElements();
void PasteElementFromClipboard();
void DuplicateSelectedElements();
void DeselectElement(IDrawableContainer container, bool generateEvents = true);
void DeselectAllElements();
/// <summary>
/// Add an element to the surface
/// </summary>
/// <param name="elements">IDrawableContainerList</param>
/// <param name="makeUndoable">Should it be placed on the undo stack?</param>
void AddElements(IDrawableContainerList elements, bool makeUndoable = true);
void RemoveElements(IDrawableContainerList elements, bool makeUndoable = true);
void SelectElements(IDrawableContainerList elements);
/// <summary>
/// Add an element to the surface
/// </summary>
/// <param name="element">IDrawableContainer</param>
/// <param name="makeUndoable">Should it be placed on the undo stack?</param>
/// <param name="invalidate">Should it be invalidated (draw)</param>
void AddElement(IDrawableContainer element, bool makeUndoable = true, bool invalidate = true);
/// <summary>
/// Select the supplied container
/// </summary>
/// <param name="container">IDrawableContainer</param>
/// <param name="invalidate">false to skip invalidation</param>
/// <param name="generateEvents">false to skip event generation</param>
void SelectElement(IDrawableContainer container, bool invalidate = true, bool generateEvents = true);
/// <summary>
/// Is the supplied container "on" the surface?
/// </summary>
/// <param name="container"></param>
/// <returns>This returns false if the container is deleted but still in the undo stack</returns>
bool IsOnSurface(IDrawableContainer container);
void Invalidate(Rectangle rectangleToInvalidate);
void Invalidate();
bool Modified
{
get;
set;
}
string LastSaveFullPath
{
get;
set;
}
string UploadUrl
{
get;
set;
}
/// <summary>
/// Remove an element of the elements list
/// </summary>
/// <param name="elementToRemove">Element to remove</param>
/// <param name="makeUndoable">flag specifying if the remove needs to be undoable</param>
/// <param name="invalidate">flag specifying if an surface invalidate needs to be called</param>
/// <param name="generateEvents">flag specifying if the deselect needs to generate an event</param>
void RemoveElement(IDrawableContainer elementToRemove, bool makeUndoable = true, bool invalidate = true, bool generateEvents = true);
void SendMessageEvent(object source, SurfaceMessageTyp messageType, string message);
void ApplyBitmapEffect(IEffect effect);
void RemoveCursor();
bool HasCursor
{
get;
}
ICaptureDetails CaptureDetails
{
get;
set;
}
int Width { get; }
int Height { get; }
void MakeUndoable(IMemento memento, bool allowMerge);
}
}

View file

@ -0,0 +1,46 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Drawing;
using System.Threading.Tasks;
namespace GreenshotPlugin.Interfaces.Ocr
{
/// <summary>
/// This interface describes something that can do OCR of a bitmap
/// </summary>
public interface IOcrProvider
{
/// <summary>
/// Start the actual OCR
/// </summary>
/// <param name="image">Image</param>
/// <returns>OcrInformation</returns>
Task<OcrInformation> DoOcrAsync(Image image);
/// <summary>
/// Start the actual OCR
/// </summary>
/// <param name="surface">ISurface</param>
/// <returns>OcrInformation</returns>
Task<OcrInformation> DoOcrAsync(ISurface surface);
}
}

View file

@ -0,0 +1,81 @@
using System.Drawing;
namespace GreenshotPlugin.Interfaces.Ocr
{
/// <summary>
/// Describes a line of words
/// </summary>
public class Line
{
private Rectangle? _calculatedBounds;
/// <summary>
/// Constructor will preallocate the number of words
/// </summary>
/// <param name="wordCount">int</param>
public Line(int wordCount)
{
Words = new Word[wordCount];
for (int i = 0; i < wordCount; i++)
{
Words[i] = new Word();
}
}
/// <summary>
/// The text of the line
/// </summary>
public string Text { get; set; }
/// <summary>
/// An array with words
/// </summary>
public Word[] Words { get; }
/// <summary>
/// Calculate the bounds of the words
/// </summary>
/// <returns>Rectangle</returns>
private Rectangle CalculateBounds()
{
if (Words.Length == 0)
{
return Rectangle.Empty;
}
var result = Words[0].Bounds;
for (var index = 0; index < Words.Length; index++)
{
result = Rectangle.Union(result, Words[index].Bounds);
}
return result;
}
/// <summary>
/// Return the calculated bounds for the whole line
/// </summary>
public Rectangle CalculatedBounds
{
get { return _calculatedBounds ??= CalculateBounds(); }
}
/// <summary>
/// Offset the words with the specified x and y coordinates
/// </summary>
/// <param name="x">int</param>
/// <param name="y">int</param>
public void Offset(int x, int y)
{
foreach (var word in Words)
{
var location = word.Bounds;
location.Offset(x,y);
word.Bounds = location;
}
_calculatedBounds = null;
CalculateBounds();
}
}
}

View file

@ -0,0 +1,46 @@
using System.Collections.Generic;
using System.Text;
namespace GreenshotPlugin.Interfaces.Ocr
{
/// <summary>
/// Contains all the information on the OCR result
/// </summary>
public class OcrInformation
{
/// <summary>
/// The complete text
/// </summary>
public string Text
{
get
{
// Build the text from the lines, otherwise it's just everything concatenated together
var text = new StringBuilder();
foreach (var line in Lines)
{
text.AppendLine(line.Text);
}
return text.ToString();
}
}
/// <summary>
/// The lines of test which the OCR engine found
/// </summary>
public IList<Line> Lines { get; } = new List<Line>();
/// <summary>
/// Change the offset of the
/// </summary>
/// <param name="x">int</param>
/// <param name="y">int</param>
public void Offset(int x, int y)
{
foreach (var line in Lines)
{
line.Offset(x,y);
}
}
}
}

View file

@ -0,0 +1,20 @@
using System.Drawing;
namespace GreenshotPlugin.Interfaces.Ocr
{
/// <summary>
/// Contains the information about a word
/// </summary>
public class Word
{
/// <summary>
/// The actual text for the word
/// </summary>
public string Text { get; set; }
/// <summary>
/// The bounds of the word
/// </summary>
public Rectangle Bounds { get; set; }
}
}

View file

@ -0,0 +1,30 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotPlugin.Interfaces
{
public enum ScreenCaptureMode
{
Auto,
FullScreen,
Fixed
};
}

View file

@ -0,0 +1,34 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
namespace GreenshotPlugin.Interfaces
{
public class SurfaceDrawingModeEventArgs : EventArgs
{
public DrawingModes DrawingMode
{
get;
set;
}
}
}

View file

@ -0,0 +1,25 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotPlugin.Interfaces
{
public delegate void SurfaceDrawingModeEventHandler(object sender, SurfaceDrawingModeEventArgs e);
}

View file

@ -0,0 +1,35 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using GreenshotPlugin.Interfaces.Drawing;
namespace GreenshotPlugin.Interfaces
{
public class SurfaceElementEventArgs : EventArgs
{
public IDrawableContainerList Elements
{
get;
set;
}
}
}

View file

@ -0,0 +1,25 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotPlugin.Interfaces
{
public delegate void SurfaceElementEventHandler(object sender, SurfaceElementEventArgs e);
}

View file

@ -0,0 +1,44 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
namespace GreenshotPlugin.Interfaces
{
public class SurfaceMessageEventArgs : EventArgs
{
public SurfaceMessageTyp MessageType
{
get;
set;
}
public string Message
{
get;
set;
}
public ISurface Surface
{
get;
set;
}
}
}

View file

@ -0,0 +1,25 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotPlugin.Interfaces
{
public delegate void SurfaceMessageEventHandler(object sender, SurfaceMessageEventArgs e);
}

View file

@ -0,0 +1,31 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotPlugin.Interfaces
{
public enum SurfaceMessageTyp
{
FileSaved,
Error,
Info,
UploadedUri
}
}

View file

@ -0,0 +1,27 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
namespace GreenshotPlugin.Interfaces
{
public delegate void SurfaceSizeChangeEventHandler(object sender, EventArgs e);
}

View file

@ -0,0 +1,34 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotPlugin.Interfaces
{
/// <summary>
/// Alignment Enums for positioning
/// </summary>
//public enum HorizontalAlignment {LEFT, CENTER, RIGHT};
public enum VerticalAlignment
{
TOP,
CENTER,
BOTTOM
};
}

View file

@ -22,12 +22,12 @@
using System.IO;
using Windows.Storage.Streams;
namespace GreenshotWin10Plugin
namespace GreenshotWin10Plugin.Internal
{
/// <summary>
/// This is an IRandomAccessStream implementation which uses a MemoryStream
/// </summary>
public sealed class MemoryRandomAccessStream : MemoryStream, IRandomAccessStream
internal sealed class MemoryRandomAccessStream : MemoryStream, IRandomAccessStream
{
/// <summary>
/// Default constructor

View file

@ -0,0 +1,43 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Threading.Tasks;
using Windows.ApplicationModel.DataTransfer;
namespace GreenshotWin10Plugin.Internal
{
internal class ShareInfo
{
public string ApplicationName { get; set; }
public bool AreShareProvidersRequested { get; set; }
public bool IsDeferredFileCreated { get; set; }
public DataPackageOperation CompletedWithOperation { get; set; }
public string AcceptedFormat { get; set; }
public bool IsDestroyed { get; set; }
public bool IsShareCompleted { get; set; }
public TaskCompletionSource<bool> ShareTask { get; } = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
public bool IsDataRequested { get; set; }
public IntPtr SharingHwnd { get; set; }
}
}

View file

@ -26,9 +26,9 @@ using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Media.Ocr;
using GreenshotPlugin.Core;
using System.Text;
using Windows.Storage.Streams;
using GreenshotPlugin.Interfaces;
using GreenshotPlugin.Interfaces.Ocr;
using GreenshotPlugin.Interfaces.Plugin;
namespace GreenshotWin10Plugin
@ -112,31 +112,39 @@ namespace GreenshotWin10Plugin
var ocrResult = await ocrEngine.RecognizeAsync(softwareBitmap);
var result = new OcrInformation();
// Build the text from the lines, otherwise it's just everything concatenated together
var text = new StringBuilder();
foreach (var line in ocrResult.Lines)
{
text.AppendLine(line.Text);
return CreateOcrInformation(ocrResult);
}
result.Text = text.ToString();
/// <summary>
/// Create the OcrInformation
/// </summary>
/// <param name="ocrResult">OcrResult</param>
/// <returns>OcrInformation</returns>
private OcrInformation CreateOcrInformation(OcrResult ocrResult)
{
var result = new OcrInformation();
foreach (var ocrLine in ocrResult.Lines)
{
var line = new Line(ocrLine.Words.Count);
var line = new Line(ocrLine.Words.Count)
{
Text = ocrLine.Text
};
result.Lines.Add(line);
for (var index = 0; index < ocrLine.Words.Count; index++)
{
var ocrWord = ocrLine.Words[index];
var location = new Rectangle((int) ocrWord.BoundingRect.X, (int) ocrWord.BoundingRect.Y,
(int) ocrWord.BoundingRect.Width, (int) ocrWord.BoundingRect.Height);
var location = new Rectangle((int)ocrWord.BoundingRect.X, (int)ocrWord.BoundingRect.Y,
(int)ocrWord.BoundingRect.Width, (int)ocrWord.BoundingRect.Height);
var word = line.Words[index];
word.Text = ocrWord.Text;
word.Location = location;
word.Bounds = location;
}
}
return result;
}

View file

@ -25,7 +25,6 @@ using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
using Windows.ApplicationModel.DataTransfer;
using Windows.Storage;
using Windows.Storage.Streams;
using Color = Windows.UI.Color;
@ -36,6 +35,7 @@ using System.Windows.Media;
using GreenshotPlugin.Hooking;
using GreenshotPlugin.Interfaces;
using GreenshotPlugin.Interfaces.Plugin;
using GreenshotWin10Plugin.Internal;
namespace GreenshotWin10Plugin
{
@ -54,22 +54,6 @@ namespace GreenshotWin10Plugin
/// </summary>
public override Image DisplayIcon => PluginUtils.GetCachedExeIcon(FilenameHelper.FillCmdVariables(@"%windir%\system32\shell32.dll"), 238);
private class ShareInfo
{
public string ApplicationName { get; set; }
public bool AreShareProvidersRequested { get; set; }
public bool IsDeferredFileCreated { get; set; }
public DataPackageOperation CompletedWithOperation { get; set; }
public string AcceptedFormat { get; set; }
public bool IsDestroyed { get; set; }
public bool IsShareCompleted { get; set; }
public TaskCompletionSource<bool> ShareTask { get; } = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
public bool IsDataRequested { get; set; }
public IntPtr SharingHwnd { get; set; }
}
/// <summary>
/// Share the screenshot with a windows app
/// </summary>
@ -102,7 +86,8 @@ namespace GreenshotWin10Plugin
// This is a bad trick, but don't know how else to do it.
// Wait for the focus to return, and depending on the state close the window!
focusMonitor.WindowOpenCloseChangeEvent += e => {
focusMonitor.WindowOpenCloseChangeEvent += e =>
{
if (e.IsOpen)
{
@ -112,8 +97,7 @@ namespace GreenshotWin10Plugin
}
return;
}
else
{
if (e.HWnd == shareInfo.SharingHwnd)
{
if (shareInfo.ApplicationName != null)
@ -122,7 +106,6 @@ namespace GreenshotWin10Plugin
}
shareInfo.ShareTask.TrySetResult(false);
}
}
};
Share(shareInfo, windowHandle, surface, captureDetails).GetAwaiter().GetResult();