Code Quality changes and dependency updates.

This commit is contained in:
Robin 2019-12-18 08:47:28 +01:00
commit 6b6bcb99bb
123 changed files with 3092 additions and 3781 deletions

View file

@ -58,11 +58,11 @@
</PropertyGroup>
<ItemGroup Condition="!$(MSBuildProjectName.Contains('Tests')) And $(MSBuildProjectName.StartsWith('Greenshot'))">
<PackageReference Include="Nerdbank.GitVersioning" Version="3.0.26">
<PackageReference Include="Nerdbank.GitVersioning" Version="3.0.28">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19351-01" PrivateAssets="All"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>
<Target Name="PostBuild" BeforeTargets="PostBuildEvent" Condition="'$(BuildingInsideVisualStudio)' == 'true' And $(MSBuildProjectName.Contains('Addon.')) And !$(MSBuildProjectName.Contains('Test')) And !$(MSBuildProjectName.Contains('Demo'))">

View file

@ -117,13 +117,11 @@ namespace Greenshot.Addon.Box
public override IBitmapWithNativeSupport DisplayIcon
{
get
{
{
// TODO: Optimize this
using (var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "box.png"))
{
return BitmapHelper.FromStream(bitmapStream);
}
}
using var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "box.png");
return BitmapHelper.FromStream(bitmapStream);
}
}
/// <inheritdoc />
@ -163,12 +161,10 @@ namespace Greenshot.Addon.Box
}
if (url != null && _boxConfiguration.AfterUploadLinkToClipBoard)
{
using (var clipboardAccessToken = ClipboardNative.Access())
{
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(url);
}
{
using var clipboardAccessToken = ClipboardNative.Access();
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(url);
}
return url;
@ -206,58 +202,56 @@ namespace Greenshot.Addon.Box
oauthHttpBehaviour.OnHttpMessageHandlerCreated = httpMessageHandler => new OAuth2HttpMessageHandler(_oauth2Settings, oauthHttpBehaviour, httpMessageHandler);
// TODO: See if the PostAsync<Bitmap> can be used? Or at least the HttpContentFactory?
using (var imageStream = new MemoryStream())
using var imageStream = new MemoryStream();
var multiPartContent = new MultipartFormDataContent();
var parentIdContent = new StringContent(_boxConfiguration.FolderId);
parentIdContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
var multiPartContent = new MultipartFormDataContent();
var parentIdContent = new StringContent(_boxConfiguration.FolderId);
parentIdContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
Name = "\"parent_id\""
};
multiPartContent.Add(parentIdContent);
surface.WriteToStream(imageStream, CoreConfiguration, _boxConfiguration);
imageStream.Position = 0;
BoxFile response;
using (var streamContent = new StreamContent(imageStream))
{
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); //"image/" + outputSettings.Format);
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"parent_id\""
};
multiPartContent.Add(parentIdContent);
surface.WriteToStream(imageStream, CoreConfiguration, _boxConfiguration);
imageStream.Position = 0;
Name = "\"file\"",
FileName = "\"" + filename + "\""
}; // the extra quotes are important here
multiPartContent.Add(streamContent);
BoxFile response;
using (var streamContent = new StreamContent(imageStream))
{
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); //"image/" + outputSettings.Format);
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"file\"",
FileName = "\"" + filename + "\""
}; // the extra quotes are important here
multiPartContent.Add(streamContent);
oauthHttpBehaviour.MakeCurrent();
response = await UploadFileUri.PostAsync<BoxFile>(multiPartContent, cancellationToken).ConfigureAwait(false);
}
if (response == null)
{
return null;
}
if (_boxConfiguration.UseSharedLink)
{
if (response.SharedLink?.Url == null)
{
var uriForSharedLink = FilesUri.AppendSegments(response.Id);
var updateAccess = new
{
shared_link = new
{
access = "open"
}
};
oauthHttpBehaviour.MakeCurrent();
response = await uriForSharedLink.PostAsync<BoxFile>(updateAccess, cancellationToken).ConfigureAwait(false);
}
return response.SharedLink.Url;
}
return $"http://www.box.com/files/0/f/0/1/f_{response.Id}";
oauthHttpBehaviour.MakeCurrent();
response = await UploadFileUri.PostAsync<BoxFile>(multiPartContent, cancellationToken).ConfigureAwait(false);
}
if (response == null)
{
return null;
}
if (_boxConfiguration.UseSharedLink)
{
if (response.SharedLink?.Url == null)
{
var uriForSharedLink = FilesUri.AppendSegments(response.Id);
var updateAccess = new
{
shared_link = new
{
access = "open"
}
};
oauthHttpBehaviour.MakeCurrent();
response = await uriForSharedLink.PostAsync<BoxFile>(updateAccess, cancellationToken).ConfigureAwait(false);
}
return response.SharedLink.Url;
}
return $"http://www.box.com/files/0/f/0/1/f_{response.Id}";
}
}

View file

@ -123,12 +123,10 @@ namespace Greenshot.Addon.Dropbox
public override IBitmapWithNativeSupport DisplayIcon
{
get
{
{
// TODO: Optimize this by caching
using (var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "Dropbox.gif"))
{
return BitmapHelper.FromStream(bitmapStream);
}
using var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "Dropbox.gif");
return BitmapHelper.FromStream(bitmapStream);
}
}
@ -145,12 +143,10 @@ namespace Greenshot.Addon.Dropbox
exportInformation.Uri = uploadUrl;
exportInformation.ExportMade = true;
if (_dropboxPluginConfiguration.AfterUploadLinkToClipBoard)
{
using (var clipboardAccessToken = ClipboardNative.Access())
{
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(uploadUrl);
}
{
using var clipboardAccessToken = ClipboardNative.Access();
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(uploadUrl);
}
}
_exportNotification.NotifyOfExport(this, exportInformation, surface);
@ -166,30 +162,24 @@ namespace Greenshot.Addon.Dropbox
try
{
var cancellationTokenSource = new CancellationTokenSource();
using (var ownedPleaseWaitForm = _pleaseWaitFormFactory(cancellationTokenSource))
{
ownedPleaseWaitForm.Value.SetDetails("Dropbox", _dropboxLanguage.CommunicationWait);
ownedPleaseWaitForm.Value.Show();
try
{
var filename = surfaceToUpload.GenerateFilename(CoreConfiguration, _dropboxPluginConfiguration);
using (var imageStream = new MemoryStream())
{
surfaceToUpload.WriteToStream(imageStream, CoreConfiguration, _dropboxPluginConfiguration);
imageStream.Position = 0;
using (var streamContent = new StreamContent(imageStream))
{
streamContent.Headers.ContentType = new MediaTypeHeaderValue(surfaceToUpload.GenerateMimeType(CoreConfiguration, _dropboxPluginConfiguration));
dropboxUrl = await UploadAsync(filename, streamContent, null, cancellationToken).ConfigureAwait(false);
}
}
}
finally
{
ownedPleaseWaitForm.Value.Close();
}
}
}
using var ownedPleaseWaitForm = _pleaseWaitFormFactory(cancellationTokenSource);
ownedPleaseWaitForm.Value.SetDetails("Dropbox", _dropboxLanguage.CommunicationWait);
ownedPleaseWaitForm.Value.Show();
try
{
var filename = surfaceToUpload.GenerateFilename(CoreConfiguration, _dropboxPluginConfiguration);
using var imageStream = new MemoryStream();
surfaceToUpload.WriteToStream(imageStream, CoreConfiguration, _dropboxPluginConfiguration);
imageStream.Position = 0;
using var streamContent = new StreamContent(imageStream);
streamContent.Headers.ContentType = new MediaTypeHeaderValue(surfaceToUpload.GenerateMimeType(CoreConfiguration, _dropboxPluginConfiguration));
dropboxUrl = await UploadAsync(filename, streamContent, null, cancellationToken).ConfigureAwait(false);
}
finally
{
ownedPleaseWaitForm.Value.Close();
}
}
catch (Exception e)
{
Log.Error().WriteLine(e);

View file

@ -89,12 +89,10 @@ namespace Greenshot.Addon.ExternalCommand
{
exportInformation.Uri = uriMatches[0].Groups[1].Value;
using (var clipboardAccessToken = ClipboardNative.Access())
{
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(exportInformation.Uri);
}
}
using var clipboardAccessToken = ClipboardNative.Access();
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(exportInformation.Uri);
}
}
if (_externalCommandDefinition.CommandBehavior.HasFlag(CommandBehaviors.DeleteOnExit))

View file

@ -19,6 +19,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="CliWrap" Version="2.4.0" />
<PackageReference Include="CliWrap" Version="2.5.0" />
</ItemGroup>
</Project>

View file

@ -123,12 +123,10 @@ namespace Greenshot.Addon.Flickr
public override IBitmapWithNativeSupport DisplayIcon
{
get
{
{
// TODO: Optimize this by caching
using (var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "flickr.png"))
{
return BitmapHelper.FromStream(bitmapStream);
}
using var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "flickr.png");
return BitmapHelper.FromStream(bitmapStream);
}
}
@ -174,12 +172,10 @@ namespace Greenshot.Addon.Flickr
return null;
}
if (_flickrConfiguration.AfterUploadLinkToClipBoard)
{
using (var clipboardAccessToken = ClipboardNative.Access())
{
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(uploadUrl);
}
{
using var clipboardAccessToken = ClipboardNative.Access();
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(uploadUrl);
}
}
@ -222,23 +218,21 @@ namespace Greenshot.Addon.Flickr
{
surfaceToUpload.WriteToStream(stream, CoreConfiguration, _flickrConfiguration);
stream.Position = 0;
using (var streamContent = new StreamContent(stream))
using var streamContent = new StreamContent(stream);
streamContent.Headers.ContentType = new MediaTypeHeaderValue(surfaceToUpload.GenerateMimeType(CoreConfiguration, _flickrConfiguration));
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
streamContent.Headers.ContentType = new MediaTypeHeaderValue(surfaceToUpload.GenerateMimeType(CoreConfiguration, _flickrConfiguration));
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"photo\"",
FileName = "\"" + filename + "\""
};
HttpBehaviour.Current.SetConfig(new HttpRequestMessageConfiguration
{
Properties = signedParameters
});
var response = await FlickrUploadUri.PostAsync<XDocument>(streamContent, token).ConfigureAwait(false);
photoId = (from element in response?.Root?.Elements() ?? Enumerable.Empty<XElement>()
where element.Name == "photoid"
select element.Value).FirstOrDefault();
}
Name = "\"photo\"",
FileName = "\"" + filename + "\""
};
HttpBehaviour.Current.SetConfig(new HttpRequestMessageConfiguration
{
Properties = signedParameters
});
var response = await FlickrUploadUri.PostAsync<XDocument>(streamContent, token).ConfigureAwait(false);
photoId = (from element in response?.Root?.Elements() ?? Enumerable.Empty<XElement>()
where element.Name == "photoid"
select element.Value).FirstOrDefault();
}
// Get Photo Info

View file

@ -101,13 +101,11 @@ namespace Greenshot.Addon.GooglePhotos
public override IBitmapWithNativeSupport DisplayIcon
{
get
{
{
// TODO: Optimize this by caching
using (var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "GooglePhotos.png"))
{
return BitmapHelper.FromStream(bitmapStream);
}
}
using var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "GooglePhotos.png");
return BitmapHelper.FromStream(bitmapStream);
}
}
/// <inheritdoc />
@ -144,12 +142,10 @@ namespace Greenshot.Addon.GooglePhotos
}
if (url != null && _googlePhotosConfiguration.AfterUploadLinkToClipBoard)
{
using (var clipboardAccessToken = ClipboardNative.Access())
{
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(url);
}
{
using var clipboardAccessToken = ClipboardNative.Access();
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(url);
}
return url;
}
@ -191,13 +187,11 @@ namespace Greenshot.Addon.GooglePhotos
{
surface.WriteToStream(imageStream, CoreConfiguration, _googlePhotosConfiguration);
imageStream.Position = 0;
using (var content = new StreamContent(imageStream))
{
content.Headers.Add("Content-Type", surface.GenerateMimeType(CoreConfiguration, _googlePhotosConfiguration));
using var content = new StreamContent(imageStream);
content.Headers.Add("Content-Type", surface.GenerateMimeType(CoreConfiguration, _googlePhotosConfiguration));
oAuthHttpBehaviour.MakeCurrent();
response = await uploadUri.PostAsync<string>(content, token).ConfigureAwait(true);
}
oAuthHttpBehaviour.MakeCurrent();
response = await uploadUri.PostAsync<string>(content, token).ConfigureAwait(true);
}
return ParseResponse(response);

View file

@ -104,17 +104,13 @@ namespace Greenshot.Addon.Imgur
localBehaviour.UploadProgress = percent => Execute.OnUIThread(() => progress.Report((int)(percent * 100)));
}
using (var imageStream = new MemoryStream())
{
surfaceToUpload.WriteToStream(imageStream, _coreConfiguration, _imgurConfiguration);
imageStream.Position = 0;
using (var content = new StreamContent(imageStream))
{
content.Headers.Add("Content-Type", surfaceToUpload.GenerateMimeType(_coreConfiguration, _imgurConfiguration));
localBehaviour.MakeCurrent();
return await uploadUri.PostAsync<ImgurImage>(content, token).ConfigureAwait(false);
}
}
using var imageStream = new MemoryStream();
surfaceToUpload.WriteToStream(imageStream, _coreConfiguration, _imgurConfiguration);
imageStream.Position = 0;
using var content = new StreamContent(imageStream);
content.Headers.Add("Content-Type", surfaceToUpload.GenerateMimeType(_coreConfiguration, _imgurConfiguration));
localBehaviour.MakeCurrent();
return await uploadUri.PostAsync<ImgurImage>(content, token).ConfigureAwait(false);
}
/// <summary>
@ -135,17 +131,13 @@ namespace Greenshot.Addon.Imgur
localBehaviour.UploadProgress = percent => Execute.OnUIThread(() => progress.Report((int) (percent * 100)));
}
var oauthHttpBehaviour = OAuth2HttpBehaviourFactory.Create(oAuth2Settings, localBehaviour);
using (var imageStream = new MemoryStream())
{
surfaceToUpload.WriteToStream(imageStream, _coreConfiguration, _imgurConfiguration);
imageStream.Position = 0;
using (var content = new StreamContent(imageStream))
{
content.Headers.Add("Content-Type", surfaceToUpload.GenerateMimeType(_coreConfiguration, _imgurConfiguration));
oauthHttpBehaviour.MakeCurrent();
return await uploadUri.PostAsync<ImgurImage>(content, token).ConfigureAwait(false);
}
}
using var imageStream = new MemoryStream();
surfaceToUpload.WriteToStream(imageStream, _coreConfiguration, _imgurConfiguration);
imageStream.Position = 0;
using var content = new StreamContent(imageStream);
content.Headers.Add("Content-Type", surfaceToUpload.GenerateMimeType(_coreConfiguration, _imgurConfiguration));
oauthHttpBehaviour.MakeCurrent();
return await uploadUri.PostAsync<ImgurImage>(content, token).ConfigureAwait(false);
}
@ -187,27 +179,25 @@ namespace Greenshot.Addon.Imgur
{
var creditsUri = new Uri($"{_imgurConfiguration.ApiUrl}/credits.json");
Behaviour.MakeCurrent();
using (var client = HttpClientFactory.Create(creditsUri))
using var client = HttpClientFactory.Create(creditsUri);
var response = await client.GetAsync(creditsUri, token).ConfigureAwait(false);
await response.HandleErrorAsync().ConfigureAwait(false);
var creditsJson = await response.GetAsAsync<dynamic>(token).ConfigureAwait(false);
if ((creditsJson != null) && creditsJson.ContainsKey("data"))
{
var response = await client.GetAsync(creditsUri, token).ConfigureAwait(false);
await response.HandleErrorAsync().ConfigureAwait(false);
var creditsJson = await response.GetAsAsync<dynamic>(token).ConfigureAwait(false);
if ((creditsJson != null) && creditsJson.ContainsKey("data"))
dynamic data = creditsJson.data;
int credits = 0;
if (data.ContainsKey("ClientRemaining"))
{
dynamic data = creditsJson.data;
int credits = 0;
if (data.ContainsKey("ClientRemaining"))
{
credits = (int)data.ClientRemaining;
Log.Debug().WriteLine("{0}={1}", "ClientRemaining", (int)data.ClientRemaining);
}
if (data.ContainsKey("UserRemaining"))
{
credits = Math.Min(credits, (int)data.UserRemaining);
Log.Debug().WriteLine("{0}={1}", "UserRemaining", (int)data.UserRemaining);
}
_imgurConfiguration.Credits = credits;
credits = (int)data.ClientRemaining;
Log.Debug().WriteLine("{0}={1}", "ClientRemaining", (int)data.ClientRemaining);
}
if (data.ContainsKey("UserRemaining"))
{
credits = Math.Min(credits, (int)data.UserRemaining);
Log.Debug().WriteLine("{0}={1}", "UserRemaining", (int)data.UserRemaining);
}
_imgurConfiguration.Credits = credits;
}
}
@ -224,17 +214,15 @@ namespace Greenshot.Addon.Imgur
Log.Debug().WriteLine("Retrieving Imgur info for {0} with url {1}", id, imageUri);
Behaviour.MakeCurrent();
using (var client = HttpClientFactory.Create(imageUri))
using var client = HttpClientFactory.Create(imageUri);
var response = await client.GetAsync(imageUri, token).ConfigureAwait(false);
// retrieving image data seems to throw a 403 (Unauthorized) if it has been deleted
if ((response.StatusCode == HttpStatusCode.NotFound) || (response.StatusCode == HttpStatusCode.Redirect) || (response.StatusCode == HttpStatusCode.Unauthorized))
{
var response = await client.GetAsync(imageUri, token).ConfigureAwait(false);
// retrieving image data seems to throw a 403 (Unauthorized) if it has been deleted
if ((response.StatusCode == HttpStatusCode.NotFound) || (response.StatusCode == HttpStatusCode.Redirect) || (response.StatusCode == HttpStatusCode.Unauthorized))
{
return null;
}
await response.HandleErrorAsync().ConfigureAwait(false);
return await response.GetAsAsync<ImgurImage>(token).ConfigureAwait(false);
return null;
}
await response.HandleErrorAsync().ConfigureAwait(false);
return await response.GetAsAsync<ImgurImage>(token).ConfigureAwait(false);
}
/// <summary>

View file

@ -81,12 +81,10 @@ namespace Greenshot.Addon.Imgur
public override IBitmapWithNativeSupport DisplayIcon
{
get
{
// TODO: Optimize this, by caching
using (var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "Imgur.png"))
{
return BitmapHelper.FromStream(bitmapStream);
}
{
// TODO: Optimize this, by caching
using var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "Imgur.png");
return BitmapHelper.FromStream(bitmapStream);
}
}
@ -128,10 +126,11 @@ namespace Greenshot.Addon.Imgur
{
// Create thumbnail
using (var tmpImage = surfaceToUpload.GetBitmapForExport())
using (var thumbnail = tmpImage.CreateThumbnail(90, 90))
{
using var thumbnail = tmpImage.CreateThumbnail(90, 90);
imgurImage.Image = thumbnail;
}
if (_imgurConfiguration.AnonymousAccess && _imgurConfiguration.TrackHistory)
{
Log.Debug().WriteLine("Storing imgur upload for hash {0} and delete hash {1}", imgurImage.Data.Id, imgurImage.Data.Deletehash);
@ -159,11 +158,9 @@ namespace Greenshot.Addon.Imgur
try
{
using (var clipboardAccessToken = ClipboardNative.Access())
{
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(uploadUrl.AbsoluteUri);
}
using var clipboardAccessToken = ClipboardNative.Access();
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(uploadUrl.AbsoluteUri);
}
catch (Exception ex)
{

View file

@ -120,10 +120,8 @@ namespace Greenshot.Addon.Imgur.ViewModels
/// </summary>
public void ShowHistory()
{
using (var imgurHistoryViewModel = ImgurHistoryViewModelFactory())
{
WindowManager.ShowDialog(imgurHistoryViewModel.Value);
}
using var imgurHistoryViewModel = ImgurHistoryViewModelFactory();
WindowManager.ShowDialog(imgurHistoryViewModel.Value);
}
/// <summary>

View file

@ -177,11 +177,9 @@ namespace Greenshot.Addon.Imgur.ViewModels
/// </summary>
public void CopyToClipboard()
{
using (var clipboardAccessToken = ClipboardNative.Access())
{
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(SelectedImgur.Data.Link?.AbsoluteUri);
}
using var clipboardAccessToken = ClipboardNative.Access();
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(SelectedImgur.Data.Link?.AbsoluteUri);
}
/// <summary>

View file

@ -392,7 +392,7 @@ namespace Greenshot.Addon.InternetExplorer
windowToCapture = InteropWindowQuery.GetForegroundWindow();
}
// Show backgroundform after retrieving the active window..
var backgroundForm = new BackgroundForm("Internet Explorer", "Please wait while the page in Internet Explorer is captured...");
using var backgroundForm = new BackgroundForm("Internet Explorer", "Please wait while the page in Internet Explorer is captured...");
backgroundForm.Show();
//BackgroundForm backgroundForm = BackgroundForm.ShowAndWait(language.GetString(LangKey.contextmenu_captureie), language.GetString(LangKey.wait_ie_capture));
try
@ -658,12 +658,10 @@ namespace Greenshot.Addon.InternetExplorer
// Loop over the frames and clear their source area so we don't see any artifacts
foreach (var frameDocument in documentContainer.Frames)
{
using (var brush = new SolidBrush(clearColor))
{
graphicsTarget.FillRectangle(brush, frameDocument.SourceRectangle);
}
}
{
using var brush = new SolidBrush(clearColor);
graphicsTarget.FillRectangle(brush, frameDocument.SourceRectangle);
}
// Loop over the frames and capture their content
foreach (var frameDocument in documentContainer.Frames)
{

View file

@ -22,7 +22,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Dapplo.Log;
using Dapplo.Windows.Desktop;
using Microsoft.Win32;
@ -31,8 +30,6 @@ namespace Greenshot.Addon.InternetExplorer {
/// Util code for Internet Explorer
/// </summary>
public class InternetExplorerHelper {
private static readonly LogSource Log = new LogSource();
// Internet explorer Registry key
private const string IeKey = @"Software\Microsoft\Internet Explorer";

View file

@ -21,6 +21,6 @@
<ItemGroup>
<PackageReference Include="Dapplo.Jira" Version="0.9.2" />
<PackageReference Include="DynamicData" Version="6.13.13" />
<PackageReference Include="DynamicData" Version="6.14.1" />
</ItemGroup>
</Project>

View file

@ -91,7 +91,11 @@ namespace Greenshot.Addon.Jira
{
if (_jiraClient != null)
{
Task.Run(async () => await LogoutAsync()).Wait();
Task.Run(async () =>
{
await LogoutAsync();
_issueTypeBitmapCache.Dispose();
}).Wait();
}
FavIcon?.Dispose();
}
@ -251,14 +255,12 @@ namespace Greenshot.Addon.Jira
public async Task AttachAsync(string issueKey, ISurface surface, string filename = null, CancellationToken cancellationToken = default)
{
await CheckCredentialsAsync(cancellationToken).ConfigureAwait(true);
using (var memoryStream = new MemoryStream())
{
surface.WriteToStream(memoryStream, _coreConfiguration, _jiraConfiguration);
memoryStream.Seek(0, SeekOrigin.Begin);
var contentType = surface.GenerateMimeType(_coreConfiguration, _jiraConfiguration);
await _jiraClient.Attachment.AttachAsync(issueKey, memoryStream, filename ?? surface.GenerateFilename(_coreConfiguration, _jiraConfiguration), contentType, cancellationToken).ConfigureAwait(false);
}
}
using var memoryStream = new MemoryStream();
surface.WriteToStream(memoryStream, _coreConfiguration, _jiraConfiguration);
memoryStream.Seek(0, SeekOrigin.Begin);
var contentType = surface.GenerateMimeType(_coreConfiguration, _jiraConfiguration);
await _jiraClient.Attachment.AttachAsync(issueKey, memoryStream, filename ?? surface.GenerateFilename(_coreConfiguration, _jiraConfiguration), contentType, cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Add a comment to the supplied issue

View file

@ -136,16 +136,12 @@ namespace Greenshot.Addon.Jira
}
}
if (displayIcon == null)
{
using (var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "jira.svgz"))
{
using (var gzStream = new GZipStream(bitmapStream, CompressionMode.Decompress))
{
displayIcon = SvgBitmap.FromStream(gzStream);
}
//displayIcon = BitmapHelper.FromStream(bitmapStream);
}
}
{
using var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "jira.svgz");
using var gzStream = new GZipStream(bitmapStream, CompressionMode.Decompress);
displayIcon = SvgBitmap.FromStream(gzStream);
//displayIcon = BitmapHelper.FromStream(bitmapStream);
}
return displayIcon;
}
}
@ -192,43 +188,41 @@ namespace Greenshot.Addon.Jira
}
}
else
{
{
// TODO: set filename
// _jiraViewModel.SetFilename(filename);
using (var jiraViewModel = _jiraViewModelFactory())
{
if (_windowManager.ShowDialog(jiraViewModel.Value) == true)
{
try
{
surface.UploadUrl = _jiraConnector.JiraBaseUri.AppendSegments("browse", jiraViewModel.Value.JiraIssue.Key).AbsoluteUri;
// Run upload in the background
using (var ownedPleaseWaitForm = _pleaseWaitFormFactory())
{
ownedPleaseWaitForm.Value.ShowAndWait(Description, _jiraLanguage.CommunicationWait,
async () =>
{
await _jiraConnector.AttachAsync(jiraViewModel.Value.JiraIssue.Key, surface,
jiraViewModel.Value.Filename).ConfigureAwait(true);
using var jiraViewModel = _jiraViewModelFactory();
if (_windowManager.ShowDialog(jiraViewModel.Value) == true)
{
try
{
surface.UploadUrl = _jiraConnector.JiraBaseUri.AppendSegments("browse", jiraViewModel.Value.JiraIssue.Key).AbsoluteUri;
// Run upload in the background
using (var ownedPleaseWaitForm = _pleaseWaitFormFactory())
{
ownedPleaseWaitForm.Value.ShowAndWait(Description, _jiraLanguage.CommunicationWait,
async () =>
{
await _jiraConnector.AttachAsync(jiraViewModel.Value.JiraIssue.Key, surface,
jiraViewModel.Value.Filename).ConfigureAwait(true);
if (!string.IsNullOrEmpty(jiraViewModel.Value.Comment))
{
await _jiraConnector.AddCommentAsync(jiraViewModel.Value.JiraIssue.Key,
jiraViewModel.Value.Comment).ConfigureAwait(true);
}
}
);
}
if (!string.IsNullOrEmpty(jiraViewModel.Value.Comment))
{
await _jiraConnector.AddCommentAsync(jiraViewModel.Value.JiraIssue.Key,
jiraViewModel.Value.Comment).ConfigureAwait(true);
}
}
);
}
Log.Debug().WriteLine("Uploaded to Jira {0}", jiraViewModel.Value.JiraIssue.Key);
exportInformation.ExportMade = true;
exportInformation.Uri = surface.UploadUrl;
}
catch (Exception e)
{
MessageBox.Show(_jiraLanguage.UploadFailure + " " + e.Message);
}
}
Log.Debug().WriteLine("Uploaded to Jira {0}", jiraViewModel.Value.JiraIssue.Key);
exportInformation.ExportMade = true;
exportInformation.Uri = surface.UploadUrl;
}
catch (Exception e)
{
MessageBox.Show(_jiraLanguage.UploadFailure + " " + e.Message);
}
}
}
_exportNotification.NotifyOfExport(this, exportInformation, surface);

View file

@ -52,19 +52,15 @@ namespace Greenshot.Addon.LegacyEditor.Controls
_selectedColor = value;
if (Image != null)
{
using (var brush = value != Color.Transparent ? new SolidBrush(value) : (Brush) new HatchBrush(HatchStyle.Percent50, Color.White, Color.Gray))
{
using (var graphics = Graphics.FromImage(Image))
{
int verticalOffset = Image.Height / 3;
int horizontalOffset = (Image.Width / 3) / 2;
int width = Image.Width - (Image.Width / 3);
int height = (Image.Height / 3) / 2;
graphics.FillRectangle(brush, new Rectangle(horizontalOffset, verticalOffset, width, height));
}
}
}
{
using var brush = value != Color.Transparent ? new SolidBrush(value) : (Brush) new HatchBrush(HatchStyle.Percent50, Color.White, Color.Gray);
using var graphics = Graphics.FromImage(Image);
int verticalOffset = Image.Height / 3;
int horizontalOffset = (Image.Width / 3) / 2;
int width = Image.Width - (Image.Width / 3);
int height = (Image.Height / 3) / 2;
graphics.FillRectangle(brush, new Rectangle(horizontalOffset, verticalOffset, width, height));
}
Invalidate();
}
}
@ -77,24 +73,22 @@ namespace Greenshot.Addon.LegacyEditor.Controls
public event PropertyChangedEventHandler PropertyChanged;
private void ColorButtonClick(object sender, EventArgs e)
{
using (var ownedColorDialog = _colorDialogFactory())
{
using var ownedColorDialog = _colorDialogFactory();
var colorDialog = ownedColorDialog.Value;
colorDialog.Color = SelectedColor;
// Using the parent to make sure the dialog doesn't show on another window
colorDialog.ShowDialog(Parent.Parent);
if (colorDialog.DialogResult == DialogResult.Cancel)
{
var colorDialog = ownedColorDialog.Value;
colorDialog.Color = SelectedColor;
// Using the parent to make sure the dialog doesn't show on another window
colorDialog.ShowDialog(Parent.Parent);
if (colorDialog.DialogResult == DialogResult.Cancel)
{
return;
}
if (colorDialog.Color.Equals(SelectedColor))
{
return;
}
SelectedColor = colorDialog.Color;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedColor"));
return;
}
}
if (colorDialog.Color.Equals(SelectedColor))
{
return;
}
SelectedColor = colorDialog.Color;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedColor"));
}
}
}

View file

@ -39,7 +39,8 @@ namespace Greenshot.Addon.LegacyEditor.Controls {
if (components != null) {
components.Dispose();
}
}
_toolTip.Dispose();
}
base.Dispose(disposing);
}

View file

@ -51,52 +51,42 @@ namespace Greenshot.Addon.LegacyEditor.Controls
}
var graphics = e.Graphics;
var dropDownRect = e.ArrowRectangle;
using (var brush = new SolidBrush(e.ArrowColor))
using var brush = new SolidBrush(e.ArrowColor);
int halfHeight = e.ArrowRectangle.Height / 2;
int halfWidth = e.ArrowRectangle.Width / 2;
var middle = new Point(dropDownRect.Left + halfWidth, dropDownRect.Top + halfHeight);
Point[] arrow;
int verticalArrowStart = middle.Y - halfHeight / 3;
int verticalArrowEnd = middle.Y + halfHeight / 3;
int horizontalArrowStart = middle.X - halfWidth;
int horizontalArrowEnd = middle.X + halfWidth;
arrow = e.Direction switch
{
int halfHeight = e.ArrowRectangle.Height / 2;
int halfWidth = e.ArrowRectangle.Width / 2;
var middle = new Point(dropDownRect.Left + halfWidth, dropDownRect.Top + halfHeight);
Point[] arrow;
int verticalArrowStart = middle.Y - halfHeight / 3;
int verticalArrowEnd = middle.Y + halfHeight / 3;
int horizontalArrowStart = middle.X - halfWidth;
int horizontalArrowEnd = middle.X + halfWidth;
switch (e.Direction)
ArrowDirection.Up => new[]
{
case ArrowDirection.Up:
arrow = new[] {
new Point(horizontalArrowStart, verticalArrowEnd),
new Point(horizontalArrowEnd, verticalArrowEnd),
new Point(middle.X, verticalArrowStart)};
break;
case ArrowDirection.Left:
arrow = new[] {
new Point(horizontalArrowEnd, verticalArrowStart),
new Point(horizontalArrowEnd, verticalArrowEnd),
new Point(horizontalArrowStart, middle.Y)};
break;
case ArrowDirection.Right:
arrow = new[] {
new Point(horizontalArrowStart, verticalArrowStart),
new Point(horizontalArrowStart, verticalArrowEnd),
new Point(horizontalArrowEnd, middle.Y)};
break;
default:
arrow = new[] {
new Point(horizontalArrowStart, verticalArrowStart),
new Point(horizontalArrowEnd, verticalArrowStart),
new Point(middle.X, verticalArrowEnd) };
break;
new Point(horizontalArrowStart, verticalArrowEnd),
new Point(horizontalArrowEnd, verticalArrowEnd), new Point(middle.X, verticalArrowStart)
},
ArrowDirection.Left => new[]
{
new Point(horizontalArrowEnd, verticalArrowStart),
new Point(horizontalArrowEnd, verticalArrowEnd), new Point(horizontalArrowStart, middle.Y)
},
ArrowDirection.Right => new[]
{
new Point(horizontalArrowStart, verticalArrowStart),
new Point(horizontalArrowStart, verticalArrowEnd), new Point(horizontalArrowEnd, middle.Y)
},
_ => new[]
{
new Point(horizontalArrowStart, verticalArrowStart),
new Point(horizontalArrowEnd, verticalArrowStart), new Point(middle.X, verticalArrowEnd)
}
graphics.FillPolygon(brush, arrow);
}
};
graphics.FillPolygon(brush, arrow);
}
}
}

View file

@ -116,17 +116,12 @@ namespace Greenshot.Addon.LegacyEditor.Controls
/// <param name="bounds"></param>
/// <param name="text"></param>
private void DrawText(Graphics graphics, FontFamily fontFamily, FontStyle fontStyle, Rectangle bounds, string text)
{
using (var font = new Font(fontFamily, Font.Size + 5, fontStyle, GraphicsUnit.Pixel))
{
// Make sure the text is visible by centering it in the line
using (var stringFormat = new StringFormat())
{
stringFormat.LineAlignment = StringAlignment.Center;
graphics.DrawString(text, font, Brushes.Black, bounds, stringFormat);
}
}
}
{
using var font = new Font(fontFamily, Font.Size + 5, fontStyle, GraphicsUnit.Pixel);
// Make sure the text is visible by centering it in the line
using var stringFormat = new StringFormat {LineAlignment = StringAlignment.Center};
graphics.DrawString(text, font, Brushes.Black, bounds, stringFormat);
}
private void BindableToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e)
{

View file

@ -39,7 +39,7 @@ namespace Greenshot.Addon.LegacyEditor.Controls
{
private const int VkEsc = 27;
private readonly IBitmapWithNativeSupport _image;
private Cursor _cursor;
private readonly Cursor _cursor;
private bool _dragging;
private MovableShowColorForm _movableShowColorForm;
@ -87,16 +87,14 @@ namespace Greenshot.Addon.LegacyEditor.Controls
/// <param name="hotspotY">Hotspot Y coordinate</param>
/// <returns>Cursor</returns>
private static Cursor CreateCursor(IBitmapWithNativeSupport bitmap, int hotspotX, int hotspotY)
{
using (var iconHandle = new SafeIconHandle(bitmap.NativeBitmap.GetHicon()))
{
NativeIconMethods.GetIconInfo(iconHandle, out var iconInfo);
iconInfo.Hotspot = new NativePoint(hotspotX, hotspotY);
iconInfo.IsIcon = false;
var icon = NativeIconMethods.CreateIconIndirect(ref iconInfo);
return new Cursor(icon);
}
}
{
using var iconHandle = new SafeIconHandle(bitmap.NativeBitmap.GetHicon());
NativeIconMethods.GetIconInfo(iconHandle, out var iconInfo);
iconInfo.Hotspot = new NativePoint(hotspotX, hotspotY);
iconInfo.IsIcon = false;
var icon = NativeIconMethods.CreateIconIndirect(ref iconInfo);
return new Cursor(icon);
}
/// <summary>
/// This Dispose is called from the Dispose and the Destructor.
@ -106,15 +104,12 @@ namespace Greenshot.Addon.LegacyEditor.Controls
{
if (disposing)
{
if (_cursor != null)
{
_cursor.Dispose();
}
_cursor.Dispose();
_movableShowColorForm?.Dispose();
_image.Dispose();
}
_movableShowColorForm = null;
_cursor = null;
base.Dispose(disposing);
base.Dispose(disposing);
}
/// <summary>

View file

@ -60,14 +60,12 @@ namespace Greenshot.Addon.LegacyEditor.Controls
}
if (Image != null)
{
using (var graphics = Graphics.FromImage(Image))
{
int quarterSize = Image.Height / 4;
var colorArea = new Rectangle(0, Image.Height - quarterSize, Image.Width, quarterSize);
graphics.FillRectangle(brush, colorArea);
}
}
{
using var graphics = Graphics.FromImage(Image);
int quarterSize = Image.Height / 4;
var colorArea = new Rectangle(0, Image.Height - quarterSize, Image.Width, quarterSize);
graphics.FillRectangle(brush, colorArea);
}
// cleanup GDI Object
brush.Dispose();
@ -84,7 +82,7 @@ namespace Greenshot.Addon.LegacyEditor.Controls
private void ColorButtonClick(object sender, EventArgs e)
{
var colorDialog = new ColorDialog(_editorConfiguration, _greenshotLanguage)
using var colorDialog = new ColorDialog(_editorConfiguration, _greenshotLanguage)
{
Color = SelectedColor
};

View file

@ -99,11 +99,8 @@ namespace Greenshot.Addon.LegacyEditor.Drawing.Adorners
var targetGraphics = paintEventArgs.Graphics;
var bounds = Bounds;
using (var brush = new SolidBrush(_color))
{
targetGraphics.FillRectangle(brush, bounds.X, bounds.Y, bounds.Width, bounds.Height);
}
using var brush = new SolidBrush(_color);
targetGraphics.FillRectangle(brush, bounds.X, bounds.Y, bounds.Width, bounds.Height);
}
/// <summary>

View file

@ -57,21 +57,14 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
return NativeRect.Empty;
}
using (var pen = new Pen(Color.White))
{
pen.Width = lineThickness;
SetArrowHeads((ArrowHeadCombination) GetFieldValue(FieldTypes.ARROWHEADS), pen);
using (var path = new GraphicsPath())
{
path.AddLine(Left, Top, Left + Width, Top + Height);
using (var matrix = new Matrix())
{
NativeRectFloat drawingBounds = path.GetBounds(matrix, pen);
return drawingBounds.Inflate(2, 2).Round();
}
}
}
}
using var pen = new Pen(Color.White) {Width = lineThickness};
SetArrowHeads((ArrowHeadCombination) GetFieldValue(FieldTypes.ARROWHEADS), pen);
using var path = new GraphicsPath();
path.AddLine(Left, Top, Left + Width, Top + Height);
using var matrix = new Matrix();
NativeRectFloat drawingBounds = path.GetBounds(matrix, pen);
return drawingBounds.Inflate(2, 2).Round();
}
}
/// <summary>
@ -109,28 +102,25 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
var steps = 5;
var currentStep = 1;
while (currentStep <= steps)
{
using (var shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness))
{
SetArrowHeads(heads, shadowCapPen);
{
using var shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness);
SetArrowHeads(heads, shadowCapPen);
graphics.DrawLine(shadowCapPen,
Left + currentStep,
Top + currentStep,
Left + currentStep + Width,
Top + currentStep + Height);
graphics.DrawLine(shadowCapPen,
Left + currentStep,
Top + currentStep,
Left + currentStep + Width,
Top + currentStep + Height);
currentStep++;
alpha = alpha - basealpha / steps;
}
}
currentStep++;
alpha = alpha - basealpha / steps;
}
}
using (var pen = new Pen(lineColor, lineThickness))
{
SetArrowHeads(heads, pen);
graphics.DrawLine(pen, Left, Top, Left + Width, Top + Height);
}
}
using var pen = new Pen(lineColor, lineThickness);
SetArrowHeads(heads, pen);
graphics.DrawLine(pen, Left, Top, Left + Width, Top + Height);
}
}
}
@ -150,18 +140,13 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
{
var lineThickness = GetFieldValueAsInt(FieldTypes.LINE_THICKNESS) + 10;
if (lineThickness > 0)
{
using (var pen = new Pen(Color.White))
{
pen.Width = lineThickness;
SetArrowHeads((ArrowHeadCombination) GetFieldValue(FieldTypes.ARROWHEADS), pen);
using (var path = new GraphicsPath())
{
path.AddLine(Left, Top, Left + Width, Top + Height);
return path.IsOutlineVisible(x, y, pen);
}
}
}
{
using var pen = new Pen(Color.White) {Width = lineThickness};
SetArrowHeads((ArrowHeadCombination) GetFieldValue(FieldTypes.ARROWHEADS), pen);
using var path = new GraphicsPath();
path.AddLine(Left, Top, Left + Width, Top + Height);
return path.IsOutlineVisible(x, y, pen);
}
return false;
}
}

View file

@ -109,14 +109,12 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
{
Log.Debug().WriteLine("Rotating element with {0} degrees.", rotateAngle);
DisposeShadow();
using (var tmpMatrix = new Matrix())
{
using (_bitmap)
{
_bitmap = _bitmap.ApplyEffect(new RotateEffect(rotateAngle), tmpMatrix);
}
}
}
using var tmpMatrix = new Matrix();
using (_bitmap)
{
_bitmap = _bitmap.ApplyEffect(new RotateEffect(rotateAngle), tmpMatrix);
}
}
base.Transform(matrix);
}
@ -225,12 +223,10 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
private void CheckShadow(bool shadow)
{
if (shadow && _shadowBitmap == null)
{
using (var matrix = new Matrix())
{
_shadowBitmap = _bitmap.ApplyEffect(new DropShadowEffect(), matrix);
}
}
{
using var matrix = new Matrix();
_shadowBitmap = _bitmap.ApplyEffect(new DropShadowEffect(), matrix);
}
}
/// <summary>

View file

@ -79,23 +79,22 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
{
return;
}
using (Brush cropBrush = new SolidBrush(Color.FromArgb(100, 150, 150, 100)))
{
var cropRectangle = new NativeRect(Left, Top, Width, Height).Normalize();
var selectionRect = new NativeRect(cropRectangle.Left - 1, cropRectangle.Top - 1, cropRectangle.Width + 1, cropRectangle.Height + 1);
DrawSelectionBorder(g, selectionRect);
using Brush cropBrush = new SolidBrush(Color.FromArgb(100, 150, 150, 100));
var cropRectangle = new NativeRect(Left, Top, Width, Height).Normalize();
var selectionRect = new NativeRect(cropRectangle.Left - 1, cropRectangle.Top - 1, cropRectangle.Width + 1, cropRectangle.Height + 1);
// top
g.FillRectangle(cropBrush, new NativeRect(0, 0, _parent.Width, cropRectangle.Top));
// left
g.FillRectangle(cropBrush, new NativeRect(0, cropRectangle.Top, cropRectangle.Left, cropRectangle.Height));
// right
g.FillRectangle(cropBrush,
new NativeRect(cropRectangle.Left + cropRectangle.Width, cropRectangle.Top, _parent.Width - (cropRectangle.Left + cropRectangle.Width), cropRectangle.Height));
// bottom
g.FillRectangle(cropBrush, new NativeRect(0, cropRectangle.Top + cropRectangle.Height, _parent.Width, _parent.Height - (cropRectangle.Top + cropRectangle.Height)));
}
}
DrawSelectionBorder(g, selectionRect);
// top
g.FillRectangle(cropBrush, new NativeRect(0, 0, _parent.Width, cropRectangle.Top));
// left
g.FillRectangle(cropBrush, new NativeRect(0, cropRectangle.Top, cropRectangle.Left, cropRectangle.Height));
// right
g.FillRectangle(cropBrush,
new NativeRect(cropRectangle.Left + cropRectangle.Width, cropRectangle.Top, _parent.Width - (cropRectangle.Left + cropRectangle.Width), cropRectangle.Height));
// bottom
g.FillRectangle(cropBrush, new NativeRect(0, cropRectangle.Top + cropRectangle.Height, _parent.Width, _parent.Height - (cropRectangle.Top + cropRectangle.Height)));
}
}
}

View file

@ -75,12 +75,11 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
{
return;
}
using (var fileCursor = new Cursor(filename))
{
Cursor = fileCursor;
Log.Debug().WriteLine("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
}
}
using var fileCursor = new Cursor(filename);
Cursor = fileCursor;
Log.Debug().WriteLine("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
}
protected override void OnDeserialized(StreamingContext streamingContext)
{

View file

@ -602,14 +602,14 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
}
protected void DrawSelectionBorder(Graphics g, NativeRect rect)
{
using (var pen = new Pen(Color.MediumSeaGreen))
{
pen.DashPattern = new float[] {1, 2};
pen.Width = 1;
g.DrawRectangle(pen, rect);
}
}
{
using var pen = new Pen(Color.MediumSeaGreen)
{
DashPattern = new float[] {1, 2},
Width = 1
};
g.DrawRectangle(pen, rect);
}
public void ResizeTo(int width, int height)

View file

@ -82,32 +82,28 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
var steps = 5;
var currentStep = lineVisible ? 1 : 0;
while (currentStep <= steps)
{
using (var shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100)))
{
shadowPen.Width = lineVisible ? lineThickness : 1;
var shadowRect = new NativeRect(rect.Left + currentStep, rect.Top + currentStep, rect.Width, rect.Height).Normalize();
graphics.DrawEllipse(shadowPen, shadowRect);
currentStep++;
alpha = alpha - basealpha / steps;
}
}
{
using var shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100))
{
Width = lineVisible ? lineThickness : 1
};
var shadowRect = new NativeRect(rect.Left + currentStep, rect.Top + currentStep, rect.Width, rect.Height).Normalize();
graphics.DrawEllipse(shadowPen, shadowRect);
currentStep++;
alpha = alpha - basealpha / steps;
}
}
//draw the original shape
if (Colors.IsVisible(fillColor))
{
using (Brush brush = new SolidBrush(fillColor))
{
graphics.FillEllipse(brush, rect);
}
}
{
using Brush brush = new SolidBrush(fillColor);
graphics.FillEllipse(brush, rect);
}
if (lineVisible)
{
using (var pen = new Pen(lineColor, lineThickness))
{
graphics.DrawEllipse(pen, rect);
}
}
{
using var pen = new Pen(lineColor, lineThickness);
graphics.DrawEllipse(pen, rect);
}
}
public override bool Contains(int x, int y)
@ -151,16 +147,12 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
// check the rest of the lines
if (lineThickness > 0)
{
using (var pen = new Pen(Color.White, lineThickness))
{
using (var path = new GraphicsPath())
{
path.AddEllipse(rect);
return path.IsOutlineVisible(x, y, pen);
}
}
}
{
using var pen = new Pen(Color.White, lineThickness);
using var path = new GraphicsPath();
path.AddEllipse(rect);
return path.IsOutlineVisible(x, y, pen);
}
return false;
}
}

View file

@ -85,24 +85,20 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
var steps = 5;
var currentStep = lineVisible ? 1 : 0;
while (currentStep <= steps)
{
using (var shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness))
{
var shadowRect = new NativeRect(Left + currentStep, Top + currentStep, Width, Height).Normalize();
graphics.DrawRectangle(shadowPen, shadowRect);
currentStep++;
alpha = alpha - baseAlpha / steps;
}
}
{
using var shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness);
var shadowRect = new NativeRect(Left + currentStep, Top + currentStep, Width, Height).Normalize();
graphics.DrawRectangle(shadowPen, shadowRect);
currentStep++;
alpha = alpha - baseAlpha / steps;
}
}
var rect = new NativeRect(Left, Top, Width, Height).Normalize();
if (lineThickness > 0)
{
using (var pen = new Pen(lineColor, lineThickness))
{
graphics.DrawRectangle(pen, rect);
}
}
{
using var pen = new Pen(lineColor, lineThickness);
graphics.DrawRectangle(pen, rect);
}
}
}
}

View file

@ -57,59 +57,58 @@ namespace Greenshot.Addon.LegacyEditor.Drawing.Filters
{
pixelSize = rect.Height;
}
using (var dest = FastBitmapFactory.CreateCloneOf(applyBitmap, area: rect))
using var dest = FastBitmapFactory.CreateCloneOf(applyBitmap, area: rect);
using (var src = FastBitmapFactory.Create(applyBitmap, rect))
{
using (var src = FastBitmapFactory.Create(applyBitmap, rect))
var halbPixelSize = pixelSize / 2;
// Create a list of x values
var xValues = new List<int>();
for (var x = src.Left - halbPixelSize; x <= src.Right + halbPixelSize; x = x + pixelSize)
{
var halbPixelSize = pixelSize / 2;
// Create a list of x values
var xValues = new List<int>();
for (var x = src.Left - halbPixelSize; x <= src.Right + halbPixelSize; x = x + pixelSize)
{
xValues.Add(x);
}
for (var y = src.Top - halbPixelSize; y < src.Bottom + halbPixelSize; y = y + pixelSize)
{
Parallel.ForEach(xValues, x =>
{
// TODO: Use stackalloc, or byte[]?
var colors = new List<Color>();
for (var yy = y; yy < y + pixelSize; yy++)
{
if (yy < src.Top || yy >= src.Bottom)
{
continue;
}
for (var xx = x; xx < x + pixelSize; xx++)
{
if (xx < src.Left || xx >= src.Right)
{
continue;
}
colors.Add(src.GetColorAt(xx, yy));
}
}
var currentAvgColor = Colors.Mix(colors);
for (var yy = y; yy <= y + pixelSize; yy++)
{
if (yy < src.Top || yy >= src.Bottom)
{
continue;
}
for (var xx = x; xx <= x + pixelSize; xx++)
{
if (xx < src.Left || xx >= src.Right)
{
continue;
}
dest.SetColorAt(xx, yy, ref currentAvgColor);
}
}
});
}
xValues.Add(x);
}
for (var y = src.Top - halbPixelSize; y < src.Bottom + halbPixelSize; y = y + pixelSize)
{
Parallel.ForEach(xValues, x =>
{
// TODO: Use stackalloc, or byte[]?
var colors = new List<Color>();
for (var yy = y; yy < y + pixelSize; yy++)
{
if (yy < src.Top || yy >= src.Bottom)
{
continue;
}
for (var xx = x; xx < x + pixelSize; xx++)
{
if (xx < src.Left || xx >= src.Right)
{
continue;
}
colors.Add(src.GetColorAt(xx, yy));
}
}
var currentAvgColor = Colors.Mix(colors);
for (var yy = y; yy <= y + pixelSize; yy++)
{
if (yy < src.Top || yy >= src.Bottom)
{
continue;
}
for (var xx = x; xx <= x + pixelSize; xx++)
{
if (xx < src.Left || xx >= src.Right)
{
continue;
}
dest.SetColorAt(xx, yy, ref currentAvgColor);
}
}
});
}
dest.DrawTo(graphics, rect.Location);
}
dest.DrawTo(graphics, rect.Location);
}
}
}

View file

@ -186,31 +186,29 @@ namespace Greenshot.Addon.LegacyEditor.Drawing {
int lineThickness = GetFieldValueAsInt(FieldTypes.LINE_THICKNESS);
var lineColor = GetFieldValueAsColor(FieldTypes.LINE_COLOR);
using (var pen = new Pen(lineColor)) {
pen.Width = lineThickness;
if (!(pen.Width > 0))
{
return;
}
// Make sure the lines are nicely rounded
pen.EndCap = LineCap.Round;
pen.StartCap = LineCap.Round;
pen.LineJoin = LineJoin.Round;
// Move to where we need to draw
graphics.TranslateTransform(Left, Top);
lock (_freehandPathLock)
{
if (_isRecalculated && Selected && renderMode == RenderMode.Edit)
{
DrawSelectionBorder(graphics, pen, _freehandPath);
}
graphics.DrawPath(pen, _freehandPath);
}
using var pen = new Pen(lineColor) {Width = lineThickness};
if (!(pen.Width > 0))
{
return;
}
// Make sure the lines are nicely rounded
pen.EndCap = LineCap.Round;
pen.StartCap = LineCap.Round;
pen.LineJoin = LineJoin.Round;
// Move to where we need to draw
graphics.TranslateTransform(Left, Top);
lock (_freehandPathLock)
{
if (_isRecalculated && Selected && renderMode == RenderMode.Edit)
{
DrawSelectionBorder(graphics, pen, _freehandPath);
}
graphics.DrawPath(pen, _freehandPath);
}
// Move back, otherwise everything is shifted
graphics.TranslateTransform(-Left,-Top);
}
}
// Move back, otherwise everything is shifted
graphics.TranslateTransform(-Left,-Top);
}
/// <summary>
/// Draw a selectionborder around the freehand path
@ -218,20 +216,19 @@ namespace Greenshot.Addon.LegacyEditor.Drawing {
/// <param name="graphics">Graphics</param>
/// <param name="linePen">Pen</param>
/// <param name="path">GraphicsPath</param>
protected static void DrawSelectionBorder(Graphics graphics, Pen linePen, GraphicsPath path) {
using (var selectionPen = (Pen) linePen.Clone()) {
using (var selectionPath = (GraphicsPath)path.Clone()) {
selectionPen.Width += 5;
selectionPen.Color = Color.FromArgb(120, Color.LightSeaGreen);
graphics.DrawPath(selectionPen, selectionPath);
selectionPath.Widen(selectionPen);
selectionPen.DashPattern = new float[]{2,2};
selectionPen.Color = Color.LightSeaGreen;
selectionPen.Width = 1;
graphics.DrawPath(selectionPen, selectionPath);
}
}
}
protected static void DrawSelectionBorder(Graphics graphics, Pen linePen, GraphicsPath path)
{
using var selectionPen = (Pen) linePen.Clone();
using var selectionPath = (GraphicsPath)path.Clone();
selectionPen.Width += 5;
selectionPen.Color = Color.FromArgb(120, Color.LightSeaGreen);
graphics.DrawPath(selectionPen, selectionPath);
selectionPath.Widen(selectionPen);
selectionPen.DashPattern = new float[]{2,2};
selectionPen.Color = Color.LightSeaGreen;
selectionPen.Width = 1;
graphics.DrawPath(selectionPen, selectionPath);
}
/// <summary>
/// Get the bounds in which we have something drawn, plus safety margin, these are not the normal bounds...
@ -276,14 +273,12 @@ namespace Greenshot.Addon.LegacyEditor.Drawing {
bool returnValue = base.ClickableAt(x, y);
if (returnValue) {
int lineThickness = GetFieldValueAsInt(FieldTypes.LINE_THICKNESS);
using (var pen = new Pen(Color.White)) {
pen.Width = lineThickness + 10;
lock (_freehandPathLock)
{
returnValue = _freehandPath.IsOutlineVisible(x - Left, y - Top, pen);
}
using var pen = new Pen(Color.White) {Width = lineThickness + 10};
lock (_freehandPathLock)
{
returnValue = _freehandPath.IsOutlineVisible(x - Left, y - Top, pen);
}
}
}
return returnValue;
}
}

View file

@ -69,12 +69,11 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
{
return;
}
using (var fileIcon = new Icon(filename))
{
Icon = fileIcon;
Log.Debug().WriteLine("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
}
}
using var fileIcon = new Icon(filename);
Icon = fileIcon;
Log.Debug().WriteLine("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
}
protected override void OnDeserialized(StreamingContext streamingContext)
{

View file

@ -91,28 +91,24 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
var steps = 5;
var currentStep = 1;
while (currentStep <= steps)
{
using (var shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness))
{
graphics.DrawLine(shadowCapPen,
Left + currentStep,
Top + currentStep,
Left + currentStep + Width,
Top + currentStep + Height);
{
using var shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness);
graphics.DrawLine(shadowCapPen,
Left + currentStep,
Top + currentStep,
Left + currentStep + Width,
Top + currentStep + Height);
currentStep++;
currentStep++;
#pragma warning disable IDE0054 // Use compound assignment
alpha = alpha - basealpha / steps;
alpha = alpha - basealpha / steps;
#pragma warning restore IDE0054 // Use compound assignment
}
}
}
}
using (var pen = new Pen(lineColor, lineThickness))
{
graphics.DrawLine(pen, Left, Top, Left + Width, Top + Height);
}
}
using var pen = new Pen(lineColor, lineThickness);
graphics.DrawLine(pen, Left, Top, Left + Width, Top + Height);
}
}
/// <inheritdoc />
@ -120,17 +116,12 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
{
var lineThickness = GetFieldValueAsInt(FieldTypes.LINE_THICKNESS) + 5;
if (lineThickness > 0)
{
using (var pen = new Pen(Color.White))
{
pen.Width = lineThickness;
using (var path = new GraphicsPath())
{
path.AddLine(Left, Top, Left + Width, Top + Height);
return path.IsOutlineVisible(x, y, pen);
}
}
}
{
using var pen = new Pen(Color.White) {Width = lineThickness};
using var path = new GraphicsPath();
path.AddLine(Left, Top, Left + Width, Top + Height);
return path.IsOutlineVisible(x, y, pen);
}
return false;
}

View file

@ -94,34 +94,33 @@ namespace Greenshot.Addon.LegacyEditor.Drawing {
int alpha = basealpha;
int steps = 5;
int currentStep = lineVisible ? 1 : 0;
while (currentStep <= steps) {
using (var shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100))) {
shadowPen.Width = lineVisible ? lineThickness : 1;
var shadowRect = new NativeRect(
rect.Left + currentStep,
rect.Top + currentStep,
rect.Width,
rect.Height).Normalize();
graphics.DrawRectangle(shadowPen, shadowRect);
currentStep++;
alpha = alpha - basealpha / steps;
}
}
while (currentStep <= steps)
{
using var shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100)) {Width = lineVisible ? lineThickness : 1};
var shadowRect = new NativeRect(
rect.Left + currentStep,
rect.Top + currentStep,
rect.Width,
rect.Height).Normalize();
graphics.DrawRectangle(shadowPen, shadowRect);
currentStep++;
alpha = alpha - basealpha / steps;
}
}
if (Colors.IsVisible(fillColor)) {
using (Brush brush = new SolidBrush(fillColor)) {
graphics.FillRectangle(brush, rect);
}
}
if (Colors.IsVisible(fillColor))
{
using Brush brush = new SolidBrush(fillColor);
graphics.FillRectangle(brush, rect);
}
graphics.SmoothingMode = SmoothingMode.HighSpeed;
if (lineVisible) {
using (var pen = new Pen(lineColor, lineThickness)) {
graphics.DrawRectangle(pen, rect);
}
}
if (lineVisible)
{
using var pen = new Pen(lineColor, lineThickness);
graphics.DrawRectangle(pen, rect);
}
}
public override bool ClickableAt(int x, int y) {
@ -143,14 +142,13 @@ namespace Greenshot.Addon.LegacyEditor.Drawing {
}
// check the rest of the lines
if (lineThickness > 0) {
using (var pen = new Pen(Color.White, lineThickness)) {
using (var path = new GraphicsPath()) {
path.AddRectangle(rect);
return path.IsOutlineVisible(x, y, pen);
}
}
}
if (lineThickness > 0)
{
using var pen = new Pen(Color.White, lineThickness);
using var path = new GraphicsPath();
path.AddRectangle(rect);
return path.IsOutlineVisible(x, y, pen);
}
return false;
}
}

View file

@ -55,18 +55,14 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
var lineThickness = GetFieldValueAsInt(FieldTypes.LINE_THICKNESS);
var lineColor = GetFieldValueAsColor(FieldTypes.LINE_COLOR);
var shadow = GetFieldValueAsBool(FieldTypes.SHADOW);
using (var pen = new Pen(lineColor, lineThickness))
{
var inflateValue = lineThickness + 2 + (shadow ? 6 : 0);
using (var tailPath = CreateTail())
{
NativeRectFloat tailBounds = tailPath.GetBounds(new Matrix(), pen);
var bounds = new NativeRect(Left, Top, Width, Height).Normalize();
using var pen = new Pen(lineColor, lineThickness);
var inflateValue = lineThickness + 2 + (shadow ? 6 : 0);
using var tailPath = CreateTail();
NativeRectFloat tailBounds = tailPath.GetBounds(new Matrix(), pen);
var bounds = new NativeRect(Left, Top, Width, Height).Normalize();
return tailBounds.Round().Union(bounds).Inflate(inflateValue, inflateValue);
}
}
}
return tailBounds.Round().Union(bounds).Inflate(inflateValue, inflateValue);
}
return NativeRect.Empty;
}
}
@ -237,37 +233,33 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
var alpha = basealpha;
const int steps = 5;
var currentStep = lineVisible ? 1 : 0;
using (var shadowMatrix = new Matrix())
using (var bubbleClone = (GraphicsPath) bubble.Clone())
using (var tailClone = (GraphicsPath) tail.Clone())
{
shadowMatrix.Translate(1, 1);
while (currentStep <= steps)
{
using (var shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100)))
{
shadowPen.Width = lineVisible ? lineThickness : 1;
tailClone.Transform(shadowMatrix);
graphics.DrawPath(shadowPen, tailClone);
bubbleClone.Transform(shadowMatrix);
graphics.DrawPath(shadowPen, bubbleClone);
}
currentStep++;
alpha = alpha - basealpha / steps;
}
}
}
using var shadowMatrix = new Matrix();
using var bubbleClone = (GraphicsPath) bubble.Clone();
using var tailClone = (GraphicsPath) tail.Clone();
shadowMatrix.Translate(1, 1);
while (currentStep <= steps)
{
using (var shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100)))
{
shadowPen.Width = lineVisible ? lineThickness : 1;
tailClone.Transform(shadowMatrix);
graphics.DrawPath(shadowPen, tailClone);
bubbleClone.Transform(shadowMatrix);
graphics.DrawPath(shadowPen, bubbleClone);
}
currentStep++;
alpha = alpha - basealpha / steps;
}
}
var state = graphics.Save();
// draw the tail border where the bubble is not visible
using (var clipRegion = new Region(bubble))
{
graphics.SetClip(clipRegion, CombineMode.Exclude);
using (var pen = new Pen(lineColor, lineThickness))
{
graphics.DrawPath(pen, tail);
}
}
using var pen = new Pen(lineColor, lineThickness);
graphics.DrawPath(pen, tail);
}
graphics.Restore(state);
if (Colors.IsVisible(fillColor))
@ -289,12 +281,10 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
using (var clipRegion = new Region(tail))
{
graphics.SetClip(clipRegion, CombineMode.Exclude);
using (var pen = new Pen(lineColor, lineThickness))
{
//pen.EndCap = pen.StartCap = LineCap.Round;
graphics.DrawPath(pen, bubble);
}
}
using var pen = new Pen(lineColor, lineThickness);
//pen.EndCap = pen.StartCap = LineCap.Round;
graphics.DrawPath(pen, bubble);
}
graphics.Restore(state);
}
@ -328,26 +318,23 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
{
var lineThickness = GetFieldValueAsInt(FieldTypes.LINE_THICKNESS);
var lineColor = GetFieldValueAsColor(FieldTypes.LINE_COLOR);
using (var pen = new Pen(lineColor, lineThickness))
{
using (var bubblePath = CreateBubble(lineThickness))
{
bubblePath.Widen(pen);
if (bubblePath.IsVisible(clickedPoint))
{
return true;
}
}
using (var tailPath = CreateTail())
{
tailPath.Widen(pen);
if (tailPath.IsVisible(clickedPoint))
{
return true;
}
}
}
}
using var pen = new Pen(lineColor, lineThickness);
using (var bubblePath = CreateBubble(lineThickness))
{
bubblePath.Widen(pen);
if (bubblePath.IsVisible(clickedPoint))
{
return true;
}
}
using var tailPath = CreateTail();
tailPath.Widen(pen);
if (tailPath.IsVisible(clickedPoint))
{
return true;
}
}
return false;
}

View file

@ -195,14 +195,11 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
{
EllipseContainer.DrawEllipse(rect, graphics, rm, 0, Color.Transparent, fillColor, false);
}
using (var fam = new FontFamily(FontFamily.GenericSansSerif.Name))
{
using (var font = new Font(fam, _fontSize, FontStyle.Bold, GraphicsUnit.Pixel))
{
TextContainer.DrawText(graphics, rect, 0, lineColor, false, _stringFormat, text, font);
}
}
}
using var fam = new FontFamily(FontFamily.GenericSansSerif.Name);
using var font = new Font(fam, _fontSize, FontStyle.Bold, GraphicsUnit.Pixel);
TextContainer.DrawText(graphics, rect, 0, lineColor, false, _stringFormat, text, font);
}
public override bool ClickableAt(int x, int y)
{

View file

@ -257,6 +257,7 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
/// </summary>
/// <param name="coreConfiguration">ICoreConfiguration</param>
/// <param name="editorConfiguration">IEditorConfiguration</param>
/// <param name="editorLanguage">IEditorLanguage</param>
/// <param name="newBitmap">IBitmapWithNativeSupport</param>
public Surface(ICoreConfiguration coreConfiguration, IEditorConfiguration editorConfiguration, IEditorLanguage editorLanguage, IBitmapWithNativeSupport newBitmap) : this(coreConfiguration, editorConfiguration, editorLanguage)
{
@ -563,7 +564,7 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
/// <param name="effect"></param>
public void ApplyBitmapEffect(IEffect effect)
{
var backgroundForm = new BackgroundForm("Effect", "Please wait");
using var backgroundForm = new BackgroundForm("Effect", "Please wait");
backgroundForm.Show();
Application.DoEvents();
try
@ -1079,7 +1080,8 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
protected override void Dispose(bool disposing)
{
if (disposing)
// TODO: Check if we need to dispose _cursorContainer
if (disposing)
{
Count--;
Log.Debug().WriteLine("Disposing surface!");
@ -2035,14 +2037,12 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
{
var uri = new Uri(possibleUrl);
using (var image = uri.GetAsAsync<Bitmap>().Result)
{
if (image != null)
{
AddImageContainer(BitmapWrapper.FromBitmap(image), mouse.X, mouse.Y);
return;
}
}
using var image = uri.GetAsAsync<Bitmap>().Result;
if (image != null)
{
AddImageContainer(BitmapWrapper.FromBitmap(image), mouse.X, mouse.Y);
return;
}
}
}
catch (Exception ex)
@ -2054,15 +2054,13 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
{
var uri = new Uri(possibleUrl);
using (var image = uri.GetAsAsync<Bitmap>().Result)
{
if (image != null)
{
AddImageContainer(BitmapWrapper.FromBitmap(image), mouse.X, mouse.Y);
return;
}
}
}
using var image = uri.GetAsAsync<Bitmap>().Result;
if (image != null)
{
AddImageContainer(BitmapWrapper.FromBitmap(image), mouse.X, mouse.Y);
return;
}
}
}
foreach (var image in ClipboardHelper.GetBitmaps(e.Data))

View file

@ -262,8 +262,8 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
};
_textBox.DataBindings.Add("Text", this, "Text", false, DataSourceUpdateMode.OnPropertyChanged);
_textBox.LostFocus += textBox_LostFocus;
_textBox.KeyDown += textBox_KeyDown;
_textBox.LostFocus += TextBox_LostFocus;
_textBox.KeyDown += TextBox_KeyDown;
}
private void ShowTextBox()
@ -306,7 +306,10 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
_parent.Focus();
_textBox?.Hide();
_parent.KeysLocked = false;
_parent.Controls.Remove(_textBox);
if (_textBox != null)
{
_parent.Controls.Remove(_textBox);
}
}
/// <summary>
@ -336,43 +339,41 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
var fontStyle = FontStyle.Regular;
bool hasStyle = false;
using (var fontFamily = new FontFamily(fontFamilyName))
using var fontFamily = new FontFamily(fontFamilyName);
bool boldAvailable = fontFamily.IsStyleAvailable(FontStyle.Bold);
if (fontBold && boldAvailable)
{
bool boldAvailable = fontFamily.IsStyleAvailable(FontStyle.Bold);
if (fontBold && boldAvailable)
{
fontStyle |= FontStyle.Bold;
hasStyle = true;
}
bool italicAvailable = fontFamily.IsStyleAvailable(FontStyle.Italic);
if (fontItalic && italicAvailable)
{
fontStyle |= FontStyle.Italic;
hasStyle = true;
}
if (!hasStyle)
{
bool regularAvailable = fontFamily.IsStyleAvailable(FontStyle.Regular);
if (regularAvailable)
{
fontStyle = FontStyle.Regular;
}
else
{
if (boldAvailable)
{
fontStyle = FontStyle.Bold;
}
else if (italicAvailable)
{
fontStyle = FontStyle.Italic;
}
}
}
return new Font(fontFamily, fontSize, fontStyle, GraphicsUnit.Pixel);
fontStyle |= FontStyle.Bold;
hasStyle = true;
}
bool italicAvailable = fontFamily.IsStyleAvailable(FontStyle.Italic);
if (fontItalic && italicAvailable)
{
fontStyle |= FontStyle.Italic;
hasStyle = true;
}
if (!hasStyle)
{
bool regularAvailable = fontFamily.IsStyleAvailable(FontStyle.Regular);
if (regularAvailable)
{
fontStyle = FontStyle.Regular;
}
else
{
if (boldAvailable)
{
fontStyle = FontStyle.Bold;
}
else if (italicAvailable)
{
fontStyle = FontStyle.Italic;
}
}
}
return new Font(fontFamily, fontSize, fontStyle, GraphicsUnit.Pixel);
}
/// <summary>
@ -487,7 +488,7 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
_textBox.ForeColor = lineColor;
}
private void textBox_KeyDown(object sender, KeyEventArgs e)
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
// ESC and Enter/Return (w/o Shift) hide text editor
if (e.KeyCode == Keys.Escape || ((e.KeyCode == Keys.Return || e.KeyCode == Keys.Enter) && e.Modifiers == Keys.None))
@ -518,7 +519,7 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
}
}
private void textBox_LostFocus(object sender, EventArgs e)
private void TextBox_LostFocus(object sender, EventArgs e)
{
// next change will be made undoable
makeUndoable = true;
@ -593,12 +594,11 @@ namespace Greenshot.Addon.LegacyEditor.Drawing
{
shadowRect = shadowRect.Inflate(-textOffset, -textOffset);
}
using (Brush fontBrush = new SolidBrush(Color.FromArgb(alpha, 100, 100, 100)))
{
graphics.DrawString(text, font, fontBrush, (Rectangle)shadowRect, stringFormat);
currentStep++;
alpha = alpha - basealpha / steps;
}
using Brush fontBrush = new SolidBrush(Color.FromArgb(alpha, 100, 100, 100));
graphics.DrawString(text, font, fontBrush, (Rectangle)shadowRect, stringFormat);
currentStep++;
alpha = alpha - basealpha / steps;
}
}

View file

@ -66,13 +66,13 @@ namespace Greenshot.Addon.LegacyEditor
{
switch (fieldType.ValueType)
{
case var intType when fieldType.ValueType == typeof(int):
case var _ when fieldType.ValueType == typeof(int):
fieldValue = Convert.ToInt32(preferredValue);
break;
case var boolType when fieldType.ValueType == typeof(bool):
case var _ when fieldType.ValueType == typeof(bool):
fieldValue = Convert.ToBoolean(preferredValue);
break;
case var colorType when fieldType.ValueType == typeof(Color):
case var _ when fieldType.ValueType == typeof(Color):
var color = Color.FromName(preferredStringValue);
fieldValue = color;
if (Color.Empty == color)
@ -80,22 +80,22 @@ namespace Greenshot.Addon.LegacyEditor
fieldValue = Color.FromArgb(Convert.ToInt32(preferredValue));
}
break;
case var alignType when fieldType.ValueType == typeof(StringAlignment):
case var _ when fieldType.ValueType == typeof(StringAlignment):
fieldValue = Enum.Parse(typeof(StringAlignment), preferredStringValue, true);
break;
case var fieldFlagType when fieldType.ValueType == typeof(FieldFlag):
case var _ when fieldType.ValueType == typeof(FieldFlag):
fieldValue = Enum.Parse(typeof(FieldFlag), preferredStringValue, true);
break;
case var preparedFilterType when fieldType.ValueType == typeof(PreparedFilter):
case var _ when fieldType.ValueType == typeof(PreparedFilter):
fieldValue = Enum.Parse(typeof(PreparedFilter), preferredStringValue, true);
break;
case var arrowHeadCombinationType when fieldType.ValueType == typeof(ArrowContainer.ArrowHeadCombination):
case var _ when fieldType.ValueType == typeof(ArrowContainer.ArrowHeadCombination):
fieldValue = Enum.Parse(typeof(ArrowContainer.ArrowHeadCombination), preferredStringValue, true);
break;
case var floatType when fieldType.ValueType == typeof(float):
case var _ when fieldType.ValueType == typeof(float):
fieldValue = Convert.ToSingle(preferredValue, CultureInfo.InvariantCulture);
break;
case var doubleType when fieldType.ValueType == typeof(double):
case var _ when fieldType.ValueType == typeof(double):
fieldValue = Convert.ToDouble(preferredValue, CultureInfo.InvariantCulture);
break;
default:

View file

@ -41,8 +41,9 @@ namespace Greenshot.Addon.LegacyEditor.Forms {
components.Dispose();
}
}
// Make sure that clipboard changes are not longer processed.
_clipboardSubscription?.Dispose();
_destinationScaleHandler.Dispose();
// Make sure that clipboard changes are not longer processed.
_clipboardSubscription?.Dispose();
// Remove all other stuff
_disposables.Dispose();
base.Dispose(disposing);

View file

@ -350,24 +350,22 @@ namespace Greenshot.Addon.LegacyEditor.Forms
/// <param name="e"></param>
private void PropertiesToolStrip_Paint(object sender, PaintEventArgs e)
{
using (var cbBorderPen = new Pen(SystemColors.ActiveBorder))
using var cbBorderPen = new Pen(SystemColors.ActiveBorder);
// Loop over all items in the propertiesToolStrip
foreach (ToolStripItem item in propertiesToolStrip.Items)
{
// Loop over all items in the propertiesToolStrip
foreach (ToolStripItem item in propertiesToolStrip.Items)
// Only ToolStripComboBox that are visible
if (!(item is ToolStripComboBox cb) || !cb.Visible)
{
// Only ToolStripComboBox that are visible
if (!(item is ToolStripComboBox cb) || !cb.Visible)
{
continue;
}
// Calculate the rectangle
if (cb.ComboBox != null)
{
var r = new Rectangle(cb.ComboBox.Location.X - 1, cb.ComboBox.Location.Y - 1, cb.ComboBox.Size.Width + 1, cb.ComboBox.Size.Height + 1);
continue;
}
// Calculate the rectangle
if (cb.ComboBox != null)
{
var r = new Rectangle(cb.ComboBox.Location.X - 1, cb.ComboBox.Location.Y - 1, cb.ComboBox.Size.Width + 1, cb.ComboBox.Size.Height + 1);
// Draw the rectangle
e.Graphics.DrawRectangle(cbBorderPen, r);
}
// Draw the rectangle
e.Graphics.DrawRectangle(cbBorderPen, r);
}
}
}
@ -901,15 +899,14 @@ namespace Greenshot.Addon.LegacyEditor.Forms
{
return;
}
using (Stream streamWrite = File.OpenWrite(saveFileDialog.FileName))
{
_surface.SaveElementsToStream(streamWrite);
}
using Stream streamWrite = File.OpenWrite(saveFileDialog.FileName);
_surface.SaveElementsToStream(streamWrite);
}
private void LoadElementsToolStripMenuItemClick(object sender, EventArgs e)
{
var openFileDialog = new OpenFileDialog
using var openFileDialog = new OpenFileDialog
{
Filter = "Greenshot templates (*.gst)|*.gst"
};
@ -1105,14 +1102,12 @@ namespace Greenshot.Addon.LegacyEditor.Forms
private void BtnResizeClick(object sender, EventArgs e)
{
var resizeEffect = new ResizeEffect(_surface.Screenshot.Width, _surface.Screenshot.Height, true);
using (var resizeSettingsForm = _resizeSettingsFormFactory(resizeEffect))
using var resizeSettingsForm = _resizeSettingsFormFactory(resizeEffect);
var result = resizeSettingsForm.Value.ShowDialog(this);
if (result == DialogResult.OK)
{
var result = resizeSettingsForm.Value.ShowDialog(this);
if (result == DialogResult.OK)
{
_surface.ApplyBitmapEffect(resizeEffect);
UpdateUndoRedoSurfaceDependencies();
}
_surface.ApplyBitmapEffect(resizeEffect);
UpdateUndoRedoSurfaceDependencies();
}
}

View file

@ -17,7 +17,6 @@
// 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.ComponentModel;
using Dapplo.Config.Language;
namespace Greenshot.Addon.Lutim.Configuration

View file

@ -48,10 +48,8 @@ namespace Greenshot.Addon.Lutim.Entities
{
get
{
using (var memoryStream = new MemoryStream(Convert.FromBase64String(ThumbBase64)))
{
return Image.FromStream(memoryStream);
}
using var memoryStream = new MemoryStream(Convert.FromBase64String(ThumbBase64));
return Image.FromStream(memoryStream);
}
}

View file

@ -29,7 +29,6 @@ using Dapplo.HttpExtensions;
using Dapplo.Log;
using Greenshot.Addon.Lutim.Configuration;
using Greenshot.Addon.Lutim.Entities;
using Greenshot.Addons.Core;
using Greenshot.Addons.Interfaces;
namespace Greenshot.Addon.Lutim
@ -41,12 +40,10 @@ namespace Greenshot.Addon.Lutim
{
private static readonly LogSource Log = new LogSource();
private readonly ILutimConfiguration _lutimConfiguration;
private readonly ICoreConfiguration _coreConfiguration;
public LutimApi(ILutimConfiguration lutimConfiguration, ICoreConfiguration coreConfiguration)
public LutimApi(ILutimConfiguration lutimConfiguration)
{
_lutimConfiguration = lutimConfiguration;
_coreConfiguration = coreConfiguration;
}
/// <summary>
@ -87,13 +84,13 @@ namespace Greenshot.Addon.Lutim
}
catch (ArgumentException)
{
Log.Info().WriteLine("Bad format of lutim history item for short {0}", key);
Log.Info().WriteLine("Bad format of Lutim history item for short {0}", key);
_lutimConfiguration.LutimUploadHistory.Remove(key);
_lutimConfiguration.RuntimeLutimHistory.Remove(key);
}
catch (Exception e)
{
Log.Error().WriteLine(e, "Problem loading lutim history for short " + key);
Log.Error().WriteLine(e, "Problem loading Lutim history for short " + key);
}
}
}

View file

@ -84,12 +84,11 @@ namespace Greenshot.Addon.Lutim {
/// <inheritdoc />
public override IBitmapWithNativeSupport DisplayIcon {
get {
get
{
// TODO: Optimize this by caching
using (var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "Lutim.png"))
{
return BitmapHelper.FromStream(bitmapStream);
}
using var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "Lutim.png");
return BitmapHelper.FromStream(bitmapStream);
}
}
@ -155,11 +154,9 @@ namespace Greenshot.Addon.Lutim {
}
try
{
using (var clipboardAccessToken = ClipboardNative.Access())
{
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(uploadUrl);
}
using var clipboardAccessToken = ClipboardNative.Access();
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(uploadUrl);
}
catch (Exception ex)
{

View file

@ -181,11 +181,9 @@ namespace Greenshot.Addon.Lutim.ViewModels
public void CopyToClipboard()
{
// TODO: Build url
using (var clipboardAccessToken = ClipboardNative.Access())
{
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(SelectedLutim.LutimInfo.Short);
}
using var clipboardAccessToken = ClipboardNative.Access();
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(SelectedLutim.LutimInfo.Short);
}
/// <summary>

View file

@ -49,17 +49,18 @@ namespace Greenshot.Addon.Office.Destinations
/// <summary>
/// Constructor used for dependency wiring
/// </summary>
/// <param name="oneNoteExporter">OneNoteExporter</param>
/// <param name="coreConfiguration">ICoreConfiguration</param>
/// <param name="greenshotLanguage">IGreenshotLanguage</param>
/// <param name="exportNotification">ExportNotification</param>
public OneNoteDestination(
public OneNoteDestination(
OneNoteExporter oneNoteExporter,
ICoreConfiguration coreConfiguration,
IGreenshotLanguage greenshotLanguage,
ExportNotification exportNotification
) : base(coreConfiguration, greenshotLanguage)
{
this._oneNoteExporter = oneNoteExporter;
_oneNoteExporter = oneNoteExporter;
_exportNotification = exportNotification;
_exePath = PluginUtils.GetExePath("ONENOTE.EXE");
if (_exePath != null && !File.Exists(_exePath))
@ -71,6 +72,7 @@ namespace Greenshot.Addon.Office.Destinations
/// <summary>
/// Constructor used for dependency wiring, and being able to specify a page
/// </summary>
/// <param name="oneNoteExporter">OneNoteExporter</param>
/// <param name="page">OneNotePage</param>
/// <param name="coreConfiguration">ICoreConfiguration</param>
/// <param name="greenshotLanguage">IGreenshotLanguage</param>

View file

@ -49,10 +49,8 @@ namespace Greenshot.Addon.Office
private bool HasApplication(string applicationName)
{
string registryPath = $@"{applicationName}\CLSID";
using (var registryKey = Registry.ClassesRoot.OpenSubKey(registryPath, false))
{
return registryKey != null && Guid.TryParse(registryKey.GetValue(null) as string, out _);
}
using var registryKey = Registry.ClassesRoot.OpenSubKey(registryPath, false);
return registryKey != null && Guid.TryParse(registryKey.GetValue(null) as string, out _);
}
/// <summary>

View file

@ -82,24 +82,19 @@ namespace Greenshot.Addon.Office.OfficeExport
/// <returns>IEnumerable with names of the workbooks</returns>
public static IEnumerable<string> GetWorkbooks()
{
using (var excelApplication = GetExcelApplication())
using var excelApplication = GetExcelApplication();
if ((excelApplication == null) || (excelApplication.ComObject == null))
{
if ((excelApplication == null) || (excelApplication.ComObject == null))
yield break;
}
using var workbooks = DisposableCom.Create(excelApplication.ComObject.Workbooks);
for (int i = 1; i <= workbooks.ComObject.Count; i++)
{
using var workbook = DisposableCom.Create(workbooks.ComObject[i]);
if (workbook != null)
{
yield break;
}
using (var workbooks = DisposableCom.Create(excelApplication.ComObject.Workbooks))
{
for (int i = 1; i <= workbooks.ComObject.Count; i++)
{
using (var workbook = DisposableCom.Create(workbooks.ComObject[i]))
{
if (workbook != null)
{
yield return workbook.ComObject.Name;
}
}
}
yield return workbook.ComObject.Name;
}
}
}
@ -129,24 +124,19 @@ namespace Greenshot.Addon.Office.OfficeExport
/// <param name="imageSize"></param>
public static void InsertIntoExistingWorkbook(string workbookName, string tmpFile, Size imageSize)
{
using (var excelApplication = GetExcelApplication())
using var excelApplication = GetExcelApplication();
if ((excelApplication == null) || (excelApplication.ComObject == null))
{
if ((excelApplication == null) || (excelApplication.ComObject == null))
return;
}
using var workbooks = DisposableCom.Create(excelApplication.ComObject.Workbooks);
for (int i = 1; i <= workbooks.ComObject.Count; i++)
{
using var workbook = DisposableCom.Create((_Workbook)workbooks.ComObject[i]);
if ((workbook != null) && workbook.ComObject.Name.StartsWith(workbookName))
{
return;
}
using (var workbooks = DisposableCom.Create(excelApplication.ComObject.Workbooks))
{
for (int i = 1; i <= workbooks.ComObject.Count; i++)
{
using (var workbook = DisposableCom.Create((_Workbook)workbooks.ComObject[i]))
{
if ((workbook != null) && workbook.ComObject.Name.StartsWith(workbookName))
{
InsertIntoExistingWorkbook(workbook, tmpFile, imageSize);
}
}
}
InsertIntoExistingWorkbook(workbook, tmpFile, imageSize);
}
}
}
@ -159,40 +149,33 @@ namespace Greenshot.Addon.Office.OfficeExport
/// <param name="imageSize"></param>
private static void InsertIntoExistingWorkbook(IDisposableCom<_Workbook> workbook, string tmpFile, Size imageSize)
{
using (var workSheet = DisposableCom.Create(workbook.ComObject.ActiveSheet as Worksheet))
using var workSheet = DisposableCom.Create(workbook.ComObject.ActiveSheet as Worksheet);
if (workSheet == null)
{
if (workSheet == null)
{
return;
}
using (var shapes = DisposableCom.Create(workSheet.ComObject.Shapes))
{
if (shapes == null)
{
return;
}
using (var shape = DisposableCom.Create(shapes.ComObject.AddPicture(tmpFile, MsoTriState.msoFalse, MsoTriState.msoTrue, 0, 0, imageSize.Width, imageSize.Height)))
{
if (shape == null)
{
return;
}
shape.ComObject.Top = 40;
shape.ComObject.Left = 40;
shape.ComObject.LockAspectRatio = MsoTriState.msoTrue;
shape.ComObject.ScaleHeight(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromTopLeft);
shape.ComObject.ScaleWidth(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromTopLeft);
workbook.ComObject.Activate();
using (var application = DisposableCom.Create(workbook.ComObject.Application))
{
var excelWindow = InteropWindowFactory.CreateFor((IntPtr) application.ComObject.Hwnd);
excelWindow.ToForegroundAsync();
}
}
}
return;
}
using var shapes = DisposableCom.Create(workSheet.ComObject.Shapes);
if (shapes == null)
{
return;
}
using var shape = DisposableCom.Create(shapes.ComObject.AddPicture(tmpFile, MsoTriState.msoFalse, MsoTriState.msoTrue, 0, 0, imageSize.Width, imageSize.Height));
if (shape == null)
{
return;
}
shape.ComObject.Top = 40;
shape.ComObject.Left = 40;
shape.ComObject.LockAspectRatio = MsoTriState.msoTrue;
shape.ComObject.ScaleHeight(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromTopLeft);
shape.ComObject.ScaleWidth(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromTopLeft);
workbook.ComObject.Activate();
using var application = DisposableCom.Create(workbook.ComObject.Application);
var excelWindow = InteropWindowFactory.CreateFor((IntPtr) application.ComObject.Hwnd);
excelWindow.ToForegroundAsync();
}
/// <summary>
@ -202,22 +185,16 @@ namespace Greenshot.Addon.Office.OfficeExport
/// <param name="imageSize"></param>
public static void InsertIntoNewWorkbook(string tmpFile, Size imageSize)
{
using (var excelApplication = GetOrCreateExcelApplication())
using var excelApplication = GetOrCreateExcelApplication();
if (excelApplication == null)
{
if (excelApplication == null)
{
return;
}
excelApplication.ComObject.Visible = true;
using (var workbooks = DisposableCom.Create(excelApplication.ComObject.Workbooks))
{
using (var workbook = DisposableCom.Create((_Workbook)workbooks.ComObject.Add()))
{
InsertIntoExistingWorkbook(workbook, tmpFile, imageSize);
}
}
return;
}
excelApplication.ComObject.Visible = true;
using var workbooks = DisposableCom.Create(excelApplication.ComObject.Workbooks);
using var workbook = DisposableCom.Create((_Workbook)workbooks.ComObject.Add());
InsertIntoExistingWorkbook(workbook, tmpFile, imageSize);
}
}

View file

@ -57,22 +57,20 @@ namespace Greenshot.Addon.Office.OfficeExport
/// <returns>bool true if export worked</returns>
public bool ExportToNewPage(ISurface surfaceToUpload)
{
using (var oneNoteApplication = GetOrCreateOneNoteApplication())
using var oneNoteApplication = GetOrCreateOneNoteApplication();
var newPage = new OneNotePage();
string unfiledNotesSectionId = GetSectionId(oneNoteApplication, SpecialLocation.slUnfiledNotesSection);
if (unfiledNotesSectionId == null)
{
var newPage = new OneNotePage();
string unfiledNotesSectionId = GetSectionId(oneNoteApplication, SpecialLocation.slUnfiledNotesSection);
if (unfiledNotesSectionId == null)
{
return false;
}
string pageId;
oneNoteApplication.ComObject.CreateNewPage(unfiledNotesSectionId, out pageId, NewPageStyle.npsDefault);
newPage.Id = pageId;
// Set the new name, this is automatically done in the export to page
newPage.Name = surfaceToUpload.CaptureDetails.Title;
return ExportToPage(oneNoteApplication, surfaceToUpload, newPage);
return false;
}
string pageId;
oneNoteApplication.ComObject.CreateNewPage(unfiledNotesSectionId, out pageId, NewPageStyle.npsDefault);
newPage.Id = pageId;
// Set the new name, this is automatically done in the export to page
newPage.Name = surfaceToUpload.CaptureDetails.Title;
return ExportToPage(oneNoteApplication, surfaceToUpload, newPage);
}
/// <summary>
@ -83,10 +81,8 @@ namespace Greenshot.Addon.Office.OfficeExport
/// <returns>bool true if everything worked</returns>
public bool ExportToPage(ISurface surfaceToUpload, OneNotePage page)
{
using (var oneNoteApplication = GetOrCreateOneNoteApplication())
{
return ExportToPage(oneNoteApplication, surfaceToUpload, page);
}
using var oneNoteApplication = GetOrCreateOneNoteApplication();
return ExportToPage(oneNoteApplication, surfaceToUpload, page);
}
/// <summary>
@ -103,25 +99,23 @@ namespace Greenshot.Addon.Office.OfficeExport
return false;
}
using (var pngStream = new MemoryStream())
using var pngStream = new MemoryStream();
var pngOutputSettings = new SurfaceOutputSettings(_coreConfiguration, OutputFormats.png, 100, false);
ImageOutput.SaveToStream(surfaceToUpload, pngStream, pngOutputSettings);
var base64String = Convert.ToBase64String(pngStream.GetBuffer());
var imageXmlStr = string.Format(XmlImageContent, base64String, surfaceToUpload.Screenshot.Width, surfaceToUpload.Screenshot.Height);
var pageChangesXml = string.Format(XmlOutline, imageXmlStr, page.Id, OnenoteNamespace2010, page.Name);
Log.Info().WriteLine("Sending XML: {0}", pageChangesXml);
oneNoteApplication.ComObject.UpdatePageContent(pageChangesXml, DateTime.MinValue, XMLSchema.xs2010, false);
try
{
var pngOutputSettings = new SurfaceOutputSettings(_coreConfiguration, OutputFormats.png, 100, false);
ImageOutput.SaveToStream(surfaceToUpload, pngStream, pngOutputSettings);
var base64String = Convert.ToBase64String(pngStream.GetBuffer());
var imageXmlStr = string.Format(XmlImageContent, base64String, surfaceToUpload.Screenshot.Width, surfaceToUpload.Screenshot.Height);
var pageChangesXml = string.Format(XmlOutline, imageXmlStr, page.Id, OnenoteNamespace2010, page.Name);
Log.Info().WriteLine("Sending XML: {0}", pageChangesXml);
oneNoteApplication.ComObject.UpdatePageContent(pageChangesXml, DateTime.MinValue, XMLSchema.xs2010, false);
try
{
oneNoteApplication.ComObject.NavigateTo(page.Id, null, false);
}
catch (Exception ex)
{
Log.Warn().WriteLine(ex, "Unable to navigate to the target page");
}
return true;
oneNoteApplication.ComObject.NavigateTo(page.Id, null, false);
}
catch (Exception ex)
{
Log.Warn().WriteLine(ex, "Unable to navigate to the target page");
}
return true;
}
/// <summary>
@ -166,80 +160,78 @@ namespace Greenshot.Addon.Office.OfficeExport
var pages = new List<OneNotePage>();
try
{
using (var oneNoteApplication = GetOrCreateOneNoteApplication())
using var oneNoteApplication = GetOrCreateOneNoteApplication();
if (oneNoteApplication != null)
{
if (oneNoteApplication != null)
// ReSharper disable once RedundantAssignment
string notebookXml = "";
oneNoteApplication.ComObject.GetHierarchy("", HierarchyScope.hsPages, out notebookXml, XMLSchema.xs2010);
if (!string.IsNullOrEmpty(notebookXml))
{
// ReSharper disable once RedundantAssignment
string notebookXml = "";
oneNoteApplication.ComObject.GetHierarchy("", HierarchyScope.hsPages, out notebookXml, XMLSchema.xs2010);
if (!string.IsNullOrEmpty(notebookXml))
Log.Debug().WriteLine(notebookXml);
StringReader reader = null;
try
{
Log.Debug().WriteLine(notebookXml);
StringReader reader = null;
try
reader = new StringReader(notebookXml);
using var xmlReader = new XmlTextReader(reader);
reader = null;
OneNoteSection currentSection = null;
OneNoteNotebook currentNotebook = null;
while (xmlReader.Read())
{
reader = new StringReader(notebookXml);
using (var xmlReader = new XmlTextReader(reader))
if ("one:Notebook".Equals(xmlReader.Name))
{
reader = null;
OneNoteSection currentSection = null;
OneNoteNotebook currentNotebook = null;
while (xmlReader.Read())
string id = xmlReader.GetAttribute("ID");
if ((id != null) && ((currentNotebook == null) || !id.Equals(currentNotebook.Id)))
{
if ("one:Notebook".Equals(xmlReader.Name))
currentNotebook = new OneNoteNotebook
{
string id = xmlReader.GetAttribute("ID");
if ((id != null) && ((currentNotebook == null) || !id.Equals(currentNotebook.Id)))
{
currentNotebook = new OneNoteNotebook();
currentNotebook.Id = xmlReader.GetAttribute("ID");
currentNotebook.Name = xmlReader.GetAttribute("name");
}
}
if ("one:Section".Equals(xmlReader.Name))
{
string id = xmlReader.GetAttribute("ID");
if ((id != null) && ((currentSection == null) || !id.Equals(currentSection.Id)))
{
currentSection = new OneNoteSection
{
Id = xmlReader.GetAttribute("ID"),
Name = xmlReader.GetAttribute("name"),
Parent = currentNotebook
};
}
}
if ("one:Page".Equals(xmlReader.Name))
{
// Skip deleted items
if ("true".Equals(xmlReader.GetAttribute("isInRecycleBin")))
{
continue;
}
var page = new OneNotePage
{
Parent = currentSection,
Name = xmlReader.GetAttribute("name"),
Id = xmlReader.GetAttribute("ID")
};
if ((page.Id == null) || (page.Name == null))
{
continue;
}
page.IsCurrentlyViewed = "true".Equals(xmlReader.GetAttribute("isCurrentlyViewed"));
pages.Add(page);
}
Id = xmlReader.GetAttribute("ID"),
Name = xmlReader.GetAttribute("name")
};
}
}
}
finally
{
if (reader != null)
if ("one:Section".Equals(xmlReader.Name))
{
reader.Dispose();
string id = xmlReader.GetAttribute("ID");
if (id != null && (currentSection == null || !id.Equals(currentSection.Id)))
{
currentSection = new OneNoteSection
{
Id = xmlReader.GetAttribute("ID"),
Name = xmlReader.GetAttribute("name"),
Parent = currentNotebook
};
}
}
if ("one:Page".Equals(xmlReader.Name))
{
// Skip deleted items
if ("true".Equals(xmlReader.GetAttribute("isInRecycleBin")))
{
continue;
}
var page = new OneNotePage
{
Parent = currentSection,
Name = xmlReader.GetAttribute("name"),
Id = xmlReader.GetAttribute("ID")
};
if ((page.Id == null) || (page.Name == null))
{
continue;
}
page.IsCurrentlyViewed = "true".Equals(xmlReader.GetAttribute("isCurrentlyViewed"));
pages.Add(page);
}
}
}
finally
{
if (reader != null)
{
reader.Dispose();
}
}
}
@ -294,20 +286,18 @@ namespace Greenshot.Addon.Office.OfficeExport
try
{
reader = new StringReader(notebookXml);
using (var xmlReader = new XmlTextReader(reader))
using var xmlReader = new XmlTextReader(reader);
while (xmlReader.Read())
{
while (xmlReader.Read())
if (!"one:Section".Equals(xmlReader.Name))
{
if (!"one:Section".Equals(xmlReader.Name))
{
continue;
}
string id = xmlReader.GetAttribute("ID");
string path = xmlReader.GetAttribute("path");
if (unfiledNotesPath.Equals(path))
{
return id;
}
continue;
}
string id = xmlReader.GetAttribute("ID");
string path = xmlReader.GetAttribute("path");
if (unfiledNotesPath.Equals(path))
{
return id;
}
}
}

View file

@ -86,100 +86,94 @@ namespace Greenshot.Addon.Office.OfficeExport
if (_outlookVersion.Major >= (int)OfficeVersions.Office2013)
{
// Check inline "panel" for Outlook 2013
using (var activeExplorer = DisposableCom.Create((_Explorer)outlookApplication.ComObject.ActiveExplorer()))
using var activeExplorer = DisposableCom.Create((_Explorer)outlookApplication.ComObject.ActiveExplorer());
// Only if we have one and if the capture is the one we selected
if ((activeExplorer != null) && activeExplorer.ComObject.Caption.StartsWith(inspectorCaption))
{
// Only if we have one and if the capture is the one we selected
if ((activeExplorer != null) && activeExplorer.ComObject.Caption.StartsWith(inspectorCaption))
var untypedInlineResponse = activeExplorer.ComObject.ActiveInlineResponse;
using (DisposableCom.Create(untypedInlineResponse))
{
var untypedInlineResponse = activeExplorer.ComObject.ActiveInlineResponse;
using (DisposableCom.Create(untypedInlineResponse))
switch (untypedInlineResponse)
{
switch (untypedInlineResponse)
{
case MailItem mailItem:
if (!mailItem.Sent)
case MailItem mailItem:
if (!mailItem.Sent)
{
return ExportToInspector(null, activeExplorer, mailItem.Class, mailItem, tmpFile, attachmentName);
}
break;
case AppointmentItem appointmentItem:
if ((_outlookVersion.Major >= (int)OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
{
if (!string.IsNullOrEmpty(appointmentItem.Organizer) && appointmentItem.Organizer.Equals(_currentUser))
{
return ExportToInspector(null, activeExplorer, mailItem.Class, mailItem, tmpFile, attachmentName);
return ExportToInspector(null, activeExplorer, appointmentItem.Class, null, tmpFile, attachmentName);
}
break;
case AppointmentItem appointmentItem:
if ((_outlookVersion.Major >= (int)OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
{
if (!string.IsNullOrEmpty(appointmentItem.Organizer) && appointmentItem.Organizer.Equals(_currentUser))
{
return ExportToInspector(null, activeExplorer, appointmentItem.Class, null, tmpFile, attachmentName);
}
}
break;
}
}
break;
}
}
}
}
using (var inspectors = DisposableCom.Create(outlookApplication.ComObject.Inspectors))
using var inspectors = DisposableCom.Create(outlookApplication.ComObject.Inspectors);
if ((inspectors == null) || (inspectors.ComObject.Count == 0))
{
if ((inspectors == null) || (inspectors.ComObject.Count == 0))
return false;
}
Log.Debug().WriteLine("Got {0} inspectors to check", inspectors.ComObject.Count);
for (int i = 1; i <= inspectors.ComObject.Count; i++)
{
using var inspector = DisposableCom.Create((_Inspector)inspectors.ComObject[i]);
string currentCaption = inspector.ComObject.Caption;
if (!currentCaption.StartsWith(inspectorCaption))
{
return false;
continue;
}
Log.Debug().WriteLine("Got {0} inspectors to check", inspectors.ComObject.Count);
for (int i = 1; i <= inspectors.ComObject.Count; i++)
{
using (var inspector = DisposableCom.Create((_Inspector)inspectors.ComObject[i]))
{
string currentCaption = inspector.ComObject.Caption;
if (!currentCaption.StartsWith(inspectorCaption))
{
continue;
}
var currentItemUntyped = inspector.ComObject.CurrentItem;
using (DisposableCom.Create(currentItemUntyped))
{
switch (currentItemUntyped)
var currentItemUntyped = inspector.ComObject.CurrentItem;
using (DisposableCom.Create(currentItemUntyped))
{
switch (currentItemUntyped)
{
case MailItem mailItem:
if (mailItem.Sent)
{
case MailItem mailItem:
if (mailItem.Sent)
{
continue;
}
try
{
return ExportToInspector(inspector, null, mailItem.Class, mailItem, tmpFile, attachmentName);
}
catch (Exception exExport)
{
Log.Error().WriteLine(exExport, "Export to {0} failed.", currentCaption);
}
break;
case AppointmentItem appointmentItem:
if ((_outlookVersion.Major >= (int)OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
{
if (!string.IsNullOrEmpty(appointmentItem.Organizer) && !appointmentItem.Organizer.Equals(_currentUser))
{
Log.Debug().WriteLine("Not exporting, as organizer is set to {0} and currentuser {1} is not him.", appointmentItem.Organizer, _currentUser);
continue;
}
}
else
{
// skip, can't export to olAppointment
continue;
}
try
{
return ExportToInspector(inspector, null, appointmentItem.Class, null, tmpFile, attachmentName);
}
catch (Exception exExport)
{
Log.Error().WriteLine(exExport, "Export to {0} failed.", currentCaption);
}
break;
default:
continue;
continue;
}
}
try
{
return ExportToInspector(inspector, null, mailItem.Class, mailItem, tmpFile, attachmentName);
}
catch (Exception exExport)
{
Log.Error().WriteLine(exExport, "Export to {0} failed.", currentCaption);
}
break;
case AppointmentItem appointmentItem:
if ((_outlookVersion.Major >= (int)OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
{
if (!string.IsNullOrEmpty(appointmentItem.Organizer) && !appointmentItem.Organizer.Equals(_currentUser))
{
Log.Debug().WriteLine("Not exporting, as organizer is set to {0} and currentuser {1} is not him.", appointmentItem.Organizer, _currentUser);
continue;
}
}
else
{
// skip, can't export to olAppointment
continue;
}
try
{
return ExportToInspector(inspector, null, appointmentItem.Class, null, tmpFile, attachmentName);
}
catch (Exception exExport)
{
Log.Error().WriteLine(exExport, "Export to {0} failed.", currentCaption);
}
break;
default:
continue;
}
}
}
@ -239,21 +233,19 @@ namespace Greenshot.Addon.Office.OfficeExport
{
using (wordDocument)
{
using (var application = DisposableCom.Create(wordDocument.ComObject.Application))
using var application = DisposableCom.Create(wordDocument.ComObject.Application);
try
{
try
if (_wordExporter.InsertIntoExistingDocument(application, wordDocument, tmpFile, null, null))
{
if (_wordExporter.InsertIntoExistingDocument(application, wordDocument, tmpFile, null, null))
{
Log.Info().WriteLine("Inserted into Wordmail");
return true;
}
}
catch (Exception exportException)
{
Log.Error().WriteLine(exportException, "Error exporting to the word editor, trying to do it via another method");
Log.Info().WriteLine("Inserted into Wordmail");
return true;
}
}
catch (Exception exportException)
{
Log.Error().WriteLine(exportException, "Error exporting to the word editor, trying to do it via another method");
}
}
}
else if (isAppointment)
@ -296,8 +288,7 @@ namespace Greenshot.Addon.Office.OfficeExport
// The following might cause a security popup... can't ignore it.
try
{
var document2 = inspector.ComObject.HTMLEditor as IHTMLDocument2;
if (document2 != null)
if (inspector.ComObject.HTMLEditor is IHTMLDocument2 document2)
{
var selection = document2.selection;
if (selection != null)
@ -332,24 +323,20 @@ namespace Greenshot.Addon.Office.OfficeExport
}
// Create the attachment (if inlined the attachment isn't visible as attachment!)
using (var attachments = DisposableCom.Create(mailItem.Attachments))
using var attachments = DisposableCom.Create(mailItem.Attachments);
using var attachment = DisposableCom.Create(attachments.ComObject.Add(tmpFile, OlAttachmentType.olByValue, inlinePossible ? 0 : 1, attachmentName));
if (_outlookVersion.Major >= (int)OfficeVersions.Office2007)
{
using (var attachment = DisposableCom.Create(attachments.ComObject.Add(tmpFile, OlAttachmentType.olByValue, inlinePossible ? 0 : 1, attachmentName)))
// Add the content id to the attachment, this only works for Outlook >= 2007
try
{
if (_outlookVersion.Major >= (int)OfficeVersions.Office2007)
{
// Add the content id to the attachment, this only works for Outlook >= 2007
try
{
var propertyAccessor = attachment.ComObject.PropertyAccessor;
propertyAccessor.SetProperty(AttachmentContentId, contentId);
}
// ReSharper disable once EmptyGeneralCatchClause
catch
{
// Ignore
}
}
var propertyAccessor = attachment.ComObject.PropertyAccessor;
propertyAccessor.SetProperty(AttachmentContentId, contentId);
}
// ReSharper disable once EmptyGeneralCatchClause
catch
{
// Ignore
}
}
}
@ -401,135 +388,127 @@ namespace Greenshot.Addon.Office.OfficeExport
/// <param name="url"></param>
private void ExportToNewEmail(IDisposableCom<Application> outlookApplication, EmailFormat format, string tmpFile, string subject, string attachmentName, string to, string cc, string bcc, string url)
{
using (var newItem = DisposableCom.Create((MailItem)outlookApplication.ComObject.CreateItem(OlItemType.olMailItem)))
using var newItem = DisposableCom.Create((MailItem)outlookApplication.ComObject.CreateItem(OlItemType.olMailItem));
if (newItem == null)
{
if (newItem == null)
{
return;
}
var newMail = newItem.ComObject;
newMail.Subject = subject;
if (!string.IsNullOrEmpty(to))
{
newMail.To = to;
}
if (!string.IsNullOrEmpty(cc))
{
newMail.CC = cc;
}
if (!string.IsNullOrEmpty(bcc))
{
newMail.BCC = bcc;
}
newMail.BodyFormat = OlBodyFormat.olFormatHTML;
string bodyString = null;
// Read the default signature, if nothing found use empty email
try
{
bodyString = GetOutlookSignature(format);
}
catch (Exception e)
{
Log.Error().WriteLine("Problem reading signature!", e);
}
switch (format)
{
case EmailFormat.Text:
// Create the attachment (and dispose the COM object after using)
using (var attachments = DisposableCom.Create(newMail.Attachments))
return;
}
var newMail = newItem.ComObject;
newMail.Subject = subject;
if (!string.IsNullOrEmpty(to))
{
newMail.To = to;
}
if (!string.IsNullOrEmpty(cc))
{
newMail.CC = cc;
}
if (!string.IsNullOrEmpty(bcc))
{
newMail.BCC = bcc;
}
newMail.BodyFormat = OlBodyFormat.olFormatHTML;
string bodyString = null;
// Read the default signature, if nothing found use empty email
try
{
bodyString = GetOutlookSignature(format);
}
catch (Exception e)
{
Log.Error().WriteLine("Problem reading signature!", e);
}
switch (format)
{
case EmailFormat.Text:
// Create the attachment (and dispose the COM object after using)
using (var attachments = DisposableCom.Create(newMail.Attachments))
{
using (DisposableCom.Create(attachments.ComObject.Add(tmpFile, OlAttachmentType.olByValue, 1, attachmentName)))
{
using (DisposableCom.Create(attachments.ComObject.Add(tmpFile, OlAttachmentType.olByValue, 1, attachmentName)))
newMail.BodyFormat = OlBodyFormat.olFormatPlain;
if (bodyString == null)
{
newMail.BodyFormat = OlBodyFormat.olFormatPlain;
if (bodyString == null)
{
bodyString = "";
}
newMail.Body = bodyString;
}
}
break;
default:
string contentId = Path.GetFileName(tmpFile);
// Create the attachment (and dispose the COM object after using)
using (var attachments = DisposableCom.Create(newMail.Attachments))
{
using (var attachment = DisposableCom.Create(attachments.ComObject.Add(tmpFile, OlAttachmentType.olByValue, 0, attachmentName)))
{
// add content ID to the attachment
if (_outlookVersion.Major >= (int)OfficeVersions.Office2007)
{
try
{
contentId = Guid.NewGuid().ToString();
using (var propertyAccessor = DisposableCom.Create(attachment.ComObject.PropertyAccessor))
{
propertyAccessor.ComObject.SetProperty(AttachmentContentId, contentId);
}
}
catch
{
Log.Info().WriteLine("Error working with the PropertyAccessor, using filename as contentid");
contentId = Path.GetFileName(tmpFile);
}
}
bodyString = "";
}
newMail.Body = bodyString;
}
}
break;
default:
string contentId = Path.GetFileName(tmpFile);
// Create the attachment (and dispose the COM object after using)
using (var attachments = DisposableCom.Create(newMail.Attachments))
{
using var attachment = DisposableCom.Create(attachments.ComObject.Add(tmpFile, OlAttachmentType.olByValue, 0, attachmentName));
// add content ID to the attachment
if (_outlookVersion.Major >= (int)OfficeVersions.Office2007)
{
try
{
contentId = Guid.NewGuid().ToString();
using var propertyAccessor = DisposableCom.Create(attachment.ComObject.PropertyAccessor);
propertyAccessor.ComObject.SetProperty(AttachmentContentId, contentId);
}
catch
{
Log.Info().WriteLine("Error working with the PropertyAccessor, using filename as contentid");
contentId = Path.GetFileName(tmpFile);
}
}
}
newMail.BodyFormat = OlBodyFormat.olFormatHTML;
string href = "";
string hrefEnd = "";
if (!string.IsNullOrEmpty(url))
newMail.BodyFormat = OlBodyFormat.olFormatHTML;
string href = "";
string hrefEnd = "";
if (!string.IsNullOrEmpty(url))
{
href = string.Format("<A HREF=\"{0}\">", url);
hrefEnd = "</A>";
}
string htmlImgEmbedded = string.Format("<BR/>{0}<IMG border=0 hspace=0 alt=\"{1}\" align=baseline src=\"cid:{2}\">{3}<BR/>", href, attachmentName, contentId, hrefEnd);
string fallbackBody = string.Format("<HTML><BODY>{0}</BODY></HTML>", htmlImgEmbedded);
if (bodyString == null)
{
bodyString = fallbackBody;
}
else
{
int bodyIndex = bodyString.IndexOf("<body", StringComparison.CurrentCultureIgnoreCase);
if (bodyIndex >= 0)
{
href = string.Format("<A HREF=\"{0}\">", url);
hrefEnd = "</A>";
}
string htmlImgEmbedded = string.Format("<BR/>{0}<IMG border=0 hspace=0 alt=\"{1}\" align=baseline src=\"cid:{2}\">{3}<BR/>", href, attachmentName, contentId, hrefEnd);
string fallbackBody = string.Format("<HTML><BODY>{0}</BODY></HTML>", htmlImgEmbedded);
if (bodyString == null)
{
bodyString = fallbackBody;
}
else
{
int bodyIndex = bodyString.IndexOf("<body", StringComparison.CurrentCultureIgnoreCase);
bodyIndex = bodyString.IndexOf(">", bodyIndex, StringComparison.Ordinal) + 1;
if (bodyIndex >= 0)
{
bodyIndex = bodyString.IndexOf(">", bodyIndex, StringComparison.Ordinal) + 1;
if (bodyIndex >= 0)
{
bodyString = bodyString.Insert(bodyIndex, htmlImgEmbedded);
}
else
{
bodyString = fallbackBody;
}
bodyString = bodyString.Insert(bodyIndex, htmlImgEmbedded);
}
else
{
bodyString = fallbackBody;
}
}
newMail.HTMLBody = bodyString;
break;
}
// So not save, otherwise the email is always stored in Draft folder.. (newMail.Save();)
newMail.Display(false);
using (var inspector = DisposableCom.Create((_Inspector)newMail.GetInspector))
{
if (inspector != null)
{
try
else
{
inspector.ComObject.Activate();
}
// ReSharper disable once EmptyGeneralCatchClause
catch
{
// Ignore
bodyString = fallbackBody;
}
}
newMail.HTMLBody = bodyString;
break;
}
// So not save, otherwise the email is always stored in Draft folder.. (newMail.Save();)
newMail.Display(false);
using var inspector = DisposableCom.Create((_Inspector)newMail.GetInspector);
if (inspector != null)
{
try
{
inspector.ComObject.Activate();
}
// ReSharper disable once EmptyGeneralCatchClause
catch
{
// Ignore
}
}
}
@ -620,50 +599,41 @@ namespace Greenshot.Addon.Office.OfficeExport
}
string defaultProfile = (string)profilesKey.GetValue(DefaultProfileValue);
Log.Debug().WriteLine("defaultProfile={0}", defaultProfile);
using (var profileKey = profilesKey.OpenSubKey(defaultProfile + @"\" + AccountKey, false))
using var profileKey = profilesKey.OpenSubKey(defaultProfile + @"\" + AccountKey, false);
if (profileKey != null)
{
if (profileKey != null)
string[] numbers = profileKey.GetSubKeyNames();
foreach (string number in numbers)
{
string[] numbers = profileKey.GetSubKeyNames();
foreach (string number in numbers)
Log.Debug().WriteLine("Found subkey {0}", number);
using var numberKey = profileKey.OpenSubKey(number, false);
if (numberKey != null)
{
Log.Debug().WriteLine("Found subkey {0}", number);
using (var numberKey = profileKey.OpenSubKey(number, false))
byte[] val = (byte[])numberKey.GetValue(NewSignatureValue);
if (val == null)
{
if (numberKey != null)
continue;
}
string signatureName = "";
foreach (byte b in val)
{
if (b != 0)
{
byte[] val = (byte[])numberKey.GetValue(NewSignatureValue);
if (val == null)
{
continue;
}
string signatureName = "";
foreach (byte b in val)
{
if (b != 0)
{
signatureName += (char)b;
}
}
Log.Debug().WriteLine("Found email signature: {0}", signatureName);
string extension;
switch (format)
{
case EmailFormat.Text:
extension = ".txt";
break;
default:
extension = ".htm";
break;
}
string signatureFile = Path.Combine(SignaturePath, signatureName + extension);
if (File.Exists(signatureFile))
{
Log.Debug().WriteLine("Found email signature file: {0}", signatureFile);
return File.ReadAllText(signatureFile, Encoding.Default);
}
signatureName += (char)b;
}
}
Log.Debug().WriteLine("Found email signature: {0}", signatureName);
var extension = format switch
{
EmailFormat.Text => ".txt",
_ => ".htm"
};
string signatureFile = Path.Combine(SignaturePath, signatureName + extension);
if (File.Exists(signatureFile))
{
Log.Debug().WriteLine("Found email signature file: {0}", signatureFile);
return File.ReadAllText(signatureFile, Encoding.Default);
}
}
}
}
@ -694,10 +664,8 @@ namespace Greenshot.Addon.Office.OfficeExport
{
using (var mapiNamespace = DisposableCom.Create(outlookApplication.ComObject.GetNamespace("MAPI")))
{
using (var currentUser = DisposableCom.Create(mapiNamespace.ComObject.CurrentUser))
{
_currentUser = currentUser.ComObject.Name;
}
using var currentUser = DisposableCom.Create(mapiNamespace.ComObject.CurrentUser);
_currentUser = currentUser.ComObject.Name;
}
Log.Info().WriteLine("Current user: {0}", _currentUser);
}
@ -717,99 +685,91 @@ namespace Greenshot.Addon.Office.OfficeExport
IDictionary<string, OlObjectClass> inspectorCaptions = new SortedDictionary<string, OlObjectClass>();
try
{
using (var outlookApplication = GetOutlookApplication())
using var outlookApplication = GetOutlookApplication();
if (outlookApplication == null)
{
if (outlookApplication == null)
{
return inspectorCaptions;
}
return inspectorCaptions;
}
// The activeexplorer inline response only works with >= 2013, Microsoft Outlook 15.0 Object Library
if (_outlookVersion.Major >= (int)OfficeVersions.Office2013)
// The activeexplorer inline response only works with >= 2013, Microsoft Outlook 15.0 Object Library
if (_outlookVersion.Major >= (int)OfficeVersions.Office2013)
{
// Check inline "panel" for Outlook 2013
using var activeExplorer = DisposableCom.Create(outlookApplication.ComObject.ActiveExplorer());
if (activeExplorer != null)
{
// Check inline "panel" for Outlook 2013
using (var activeExplorer = DisposableCom.Create(outlookApplication.ComObject.ActiveExplorer()))
var untypedInlineResponse = activeExplorer.ComObject.ActiveInlineResponse;
if (untypedInlineResponse != null)
{
if (activeExplorer != null)
string caption = activeExplorer.ComObject.Caption;
using (DisposableCom.Create(untypedInlineResponse))
{
var untypedInlineResponse = activeExplorer.ComObject.ActiveInlineResponse;
if (untypedInlineResponse != null)
switch (untypedInlineResponse)
{
string caption = activeExplorer.ComObject.Caption;
using (DisposableCom.Create(untypedInlineResponse))
{
switch (untypedInlineResponse)
case MailItem mailItem:
if (!mailItem.Sent)
{
case MailItem mailItem:
if (!mailItem.Sent)
{
inspectorCaptions.Add(caption, mailItem.Class);
}
break;
case AppointmentItem appointmentItem:
if ((_outlookVersion.Major >= (int)OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
{
if (!string.IsNullOrEmpty(appointmentItem.Organizer) && appointmentItem.Organizer.Equals(_currentUser))
{
inspectorCaptions.Add(caption, appointmentItem.Class);
}
}
break;
inspectorCaptions.Add(caption, mailItem.Class);
}
}
break;
case AppointmentItem appointmentItem:
if ((_outlookVersion.Major >= (int)OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
{
if (!string.IsNullOrEmpty(appointmentItem.Organizer) && appointmentItem.Organizer.Equals(_currentUser))
{
inspectorCaptions.Add(caption, appointmentItem.Class);
}
}
break;
}
}
}
}
}
using (var inspectors = DisposableCom.Create(outlookApplication.ComObject.Inspectors))
using var inspectors = DisposableCom.Create(outlookApplication.ComObject.Inspectors);
if ((inspectors != null) && (inspectors.ComObject.Count > 0))
{
for (int i = 1; i <= inspectors.ComObject.Count; i++)
{
if ((inspectors != null) && (inspectors.ComObject.Count > 0))
using var inspector = DisposableCom.Create(inspectors.ComObject[i]);
string caption = inspector.ComObject.Caption;
// Fix double entries in the directory, TODO: store on something uniq
if (inspectorCaptions.ContainsKey(caption))
{
for (int i = 1; i <= inspectors.ComObject.Count; i++)
continue;
}
var currentItemUntyped = inspector.ComObject.CurrentItem;
using (DisposableCom.Create(currentItemUntyped))
{
switch (currentItemUntyped)
{
using (var inspector = DisposableCom.Create(inspectors.ComObject[i]))
{
string caption = inspector.ComObject.Caption;
// Fix double entries in the directory, TODO: store on something uniq
if (inspectorCaptions.ContainsKey(caption))
case MailItem mailItem:
if (mailItem.Sent)
{
continue;
}
var currentItemUntyped = inspector.ComObject.CurrentItem;
using (DisposableCom.Create(currentItemUntyped))
inspectorCaptions.Add(caption, mailItem.Class);
break;
case AppointmentItem appointmentItem:
if ((_outlookVersion.Major >= (int)OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
{
switch (currentItemUntyped)
if (!string.IsNullOrEmpty(appointmentItem.Organizer) && !appointmentItem.Organizer.Equals(_currentUser))
{
case MailItem mailItem:
if (mailItem.Sent)
{
continue;
}
inspectorCaptions.Add(caption, mailItem.Class);
break;
case AppointmentItem appointmentItem:
if ((_outlookVersion.Major >= (int)OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
{
if (!string.IsNullOrEmpty(appointmentItem.Organizer) && !appointmentItem.Organizer.Equals(_currentUser))
{
Log.Debug().WriteLine("Not exporting, as organizer is set to {0} and currentuser {1} is not him.", appointmentItem.Organizer, _currentUser);
continue;
}
}
else
{
// skip, can't export to olAppointment
continue;
}
inspectorCaptions.Add(caption, appointmentItem.Class);
break;
default:
continue;
Log.Debug().WriteLine("Not exporting, as organizer is set to {0} and currentuser {1} is not him.", appointmentItem.Organizer, _currentUser);
continue;
}
}
}
else
{
// skip, can't export to olAppointment
continue;
}
inspectorCaptions.Add(caption, appointmentItem.Class);
break;
default:
continue;
}
}
}

View file

@ -81,72 +81,64 @@ namespace Greenshot.Addon.Office.OfficeExport
slide = DisposableCom.Create(slides.ComObject.Add(slides.ComObject.Count + 1, _officeConfiguration.PowerpointSlideLayout));
}
using (var shapes = DisposableCom.Create(slide.ComObject.Shapes))
using var shapes = DisposableCom.Create(slide.ComObject.Shapes);
using var shapeForLocation = DisposableCom.Create(shapes.ComObject[2]);
// Shapes[2] is the image shape on this layout.
shapeForCaption = DisposableCom.Create(shapes.ComObject[1]);
if (width > shapeForLocation.ComObject.Width)
{
using (var shapeForLocation = DisposableCom.Create(shapes.ComObject[2]))
{
// Shapes[2] is the image shape on this layout.
shapeForCaption = DisposableCom.Create(shapes.ComObject[1]);
if (width > shapeForLocation.ComObject.Width)
{
width = shapeForLocation.ComObject.Width;
left = shapeForLocation.ComObject.Left;
hasScaledWidth = true;
}
else
{
shapeForLocation.ComObject.Left = left;
}
shapeForLocation.ComObject.Width = imageSize.Width;
if (height > shapeForLocation.ComObject.Height)
{
height = shapeForLocation.ComObject.Height;
top = shapeForLocation.ComObject.Top;
hasScaledHeight = true;
}
else
{
top = shapeForLocation.ComObject.Top + shapeForLocation.ComObject.Height / 2 - imageSize.Height / 2f;
}
shapeForLocation.ComObject.Height = imageSize.Height;
}
width = shapeForLocation.ComObject.Width;
left = shapeForLocation.ComObject.Left;
hasScaledWidth = true;
}
else
{
shapeForLocation.ComObject.Left = left;
}
shapeForLocation.ComObject.Width = imageSize.Width;
if (height > shapeForLocation.ComObject.Height)
{
height = shapeForLocation.ComObject.Height;
top = shapeForLocation.ComObject.Top;
hasScaledHeight = true;
}
else
{
top = shapeForLocation.ComObject.Top + shapeForLocation.ComObject.Height / 2 - imageSize.Height / 2f;
}
shapeForLocation.ComObject.Height = imageSize.Height;
}
catch (Exception e)
{
Log.Error().WriteLine(e, "Powerpoint shape creating failed");
using (var slides = DisposableCom.Create(presentation.ComObject.Slides))
{
slide = DisposableCom.Create(slides.ComObject.Add(slides.ComObject.Count + 1, PpSlideLayout.ppLayoutBlank));
}
using var slides = DisposableCom.Create(presentation.ComObject.Slides);
slide = DisposableCom.Create(slides.ComObject.Add(slides.ComObject.Count + 1, PpSlideLayout.ppLayoutBlank));
}
using (var shapes = DisposableCom.Create(slide.ComObject.Shapes))
{
using (var shape = DisposableCom.Create(shapes.ComObject.AddPicture(tmpFile, MsoTriState.msoFalse, MsoTriState.msoTrue, 0, 0, width, height)))
using var shape = DisposableCom.Create(shapes.ComObject.AddPicture(tmpFile, MsoTriState.msoFalse, MsoTriState.msoTrue, 0, 0, width, height));
if (_officeConfiguration.PowerpointLockAspectRatio)
{
if (_officeConfiguration.PowerpointLockAspectRatio)
{
shape.ComObject.LockAspectRatio = MsoTriState.msoTrue;
}
else
{
shape.ComObject.LockAspectRatio = MsoTriState.msoFalse;
}
shape.ComObject.ScaleHeight(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromMiddle);
shape.ComObject.ScaleWidth(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromMiddle);
if (hasScaledWidth)
{
shape.ComObject.Width = width;
}
if (hasScaledHeight)
{
shape.ComObject.Height = height;
}
shape.ComObject.Left = left;
shape.ComObject.Top = top;
shape.ComObject.AlternativeText = title;
shape.ComObject.LockAspectRatio = MsoTriState.msoTrue;
}
else
{
shape.ComObject.LockAspectRatio = MsoTriState.msoFalse;
}
shape.ComObject.ScaleHeight(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromMiddle);
shape.ComObject.ScaleWidth(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromMiddle);
if (hasScaledWidth)
{
shape.ComObject.Width = width;
}
if (hasScaledHeight)
{
shape.ComObject.Height = height;
}
shape.ComObject.Left = left;
shape.ComObject.Top = top;
shape.ComObject.AlternativeText = title;
}
if (shapeForCaption != null)
{
@ -155,13 +147,9 @@ namespace Greenshot.Addon.Office.OfficeExport
using (shapeForCaption)
{
// Using try/catch to make sure problems with the text range don't give an exception.
using (var textFrame = DisposableCom.Create(shapeForCaption.ComObject.TextFrame))
{
using (var textRange = DisposableCom.Create(textFrame.ComObject.TextRange))
{
textRange.ComObject.Text = title;
}
}
using var textFrame = DisposableCom.Create(shapeForCaption.ComObject.TextFrame);
using var textRange = DisposableCom.Create(textFrame.ComObject.TextRange);
textRange.ComObject.Text = title;
}
}
catch (Exception ex)
@ -172,16 +160,10 @@ namespace Greenshot.Addon.Office.OfficeExport
// Activate/Goto the slide
try
{
using (var application = DisposableCom.Create(presentation.ComObject.Application))
{
using (var activeWindow = DisposableCom.Create(application.ComObject.ActiveWindow))
{
using (var view = DisposableCom.Create(activeWindow.ComObject.View))
{
view.ComObject.GotoSlide(slide.ComObject.SlideNumber);
}
}
}
using var application = DisposableCom.Create(presentation.ComObject.Application);
using var activeWindow = DisposableCom.Create(application.ComObject.ActiveWindow);
using var view = DisposableCom.Create(activeWindow.ComObject.View);
view.ComObject.GotoSlide(slide.ComObject.SlideNumber);
}
catch (Exception ex)
{
@ -211,31 +193,28 @@ namespace Greenshot.Addon.Office.OfficeExport
{
return false;
}
using (var presentations = DisposableCom.Create(powerpointApplication.ComObject.Presentations))
using var presentations = DisposableCom.Create(powerpointApplication.ComObject.Presentations);
Log.Debug().WriteLine("Open Presentations: {0}", presentations.ComObject.Count);
for (int i = 1; i <= presentations.ComObject.Count; i++)
{
Log.Debug().WriteLine("Open Presentations: {0}", presentations.ComObject.Count);
for (int i = 1; i <= presentations.ComObject.Count; i++)
using var presentation = DisposableCom.Create(presentations.ComObject[i]);
if (presentation == null)
{
using (var presentation = DisposableCom.Create(presentations.ComObject[i]))
{
if (presentation == null)
{
continue;
}
if (!presentation.ComObject.Name.StartsWith(presentationName))
{
continue;
}
try
{
AddPictureToPresentation(presentation, tmpFile, imageSize, title);
return true;
}
catch (Exception e)
{
Log.Error().WriteLine(e, "Adding picture to powerpoint failed");
}
}
continue;
}
if (!presentation.ComObject.Name.StartsWith(presentationName))
{
continue;
}
try
{
AddPictureToPresentation(presentation, tmpFile, imageSize, title);
return true;
}
catch (Exception e)
{
Log.Error().WriteLine(e, "Adding picture to powerpoint failed");
}
}
}
@ -286,39 +265,33 @@ namespace Greenshot.Addon.Office.OfficeExport
/// <returns></returns>
public IEnumerable<string> GetPowerpointPresentations()
{
using (var powerpointApplication = GetPowerPointApplication())
using var powerpointApplication = GetPowerPointApplication();
if (powerpointApplication == null)
{
if (powerpointApplication == null)
{
yield break;
}
yield break;
}
using (var presentations = DisposableCom.Create(powerpointApplication.ComObject.Presentations))
using var presentations = DisposableCom.Create(powerpointApplication.ComObject.Presentations);
Log.Debug().WriteLine("Open Presentations: {0}", presentations.ComObject.Count);
for (int i = 1; i <= presentations.ComObject.Count; i++)
{
using var presentation = DisposableCom.Create(presentations.ComObject[i]);
if (presentation == null)
{
Log.Debug().WriteLine("Open Presentations: {0}", presentations.ComObject.Count);
for (int i = 1; i <= presentations.ComObject.Count; i++)
continue;
}
if (presentation.ComObject.ReadOnly == MsoTriState.msoTrue)
{
continue;
}
if (IsAfter2003())
{
if (presentation.ComObject.Final)
{
using (var presentation = DisposableCom.Create(presentations.ComObject[i]))
{
if (presentation == null)
{
continue;
}
if (presentation.ComObject.ReadOnly == MsoTriState.msoTrue)
{
continue;
}
if (IsAfter2003())
{
if (presentation.ComObject.Final)
{
continue;
}
}
yield return presentation.ComObject.Name;
}
continue;
}
}
yield return presentation.ComObject.Name;
}
}
@ -355,20 +328,16 @@ namespace Greenshot.Addon.Office.OfficeExport
{
powerpointApplication.ComObject.Activate();
powerpointApplication.ComObject.Visible = MsoTriState.msoTrue;
using (var presentations = DisposableCom.Create(powerpointApplication.ComObject.Presentations))
using var presentations = DisposableCom.Create(powerpointApplication.ComObject.Presentations);
using var presentation = DisposableCom.Create(presentations.ComObject.Add());
try
{
using (var presentation = DisposableCom.Create(presentations.ComObject.Add()))
{
try
{
AddPictureToPresentation(presentation, tmpFile, imageSize, title);
isPictureAdded = true;
}
catch (Exception e)
{
Log.Error().WriteLine(e, "Powerpoint add picture to presentation failed");
}
}
AddPictureToPresentation(presentation, tmpFile, imageSize, title);
isPictureAdded = true;
}
catch (Exception e)
{
Log.Error().WriteLine(e, "Powerpoint add picture to presentation failed");
}
}
}

View file

@ -55,18 +55,16 @@ namespace Greenshot.Addon.Office.OfficeExport
/// <returns></returns>
private IDisposableCom<InlineShape> AddPictureToSelection(IDisposableCom<Selection> selection, string tmpFile)
{
using (var shapes = DisposableCom.Create(selection.ComObject.InlineShapes))
using var shapes = DisposableCom.Create(selection.ComObject.InlineShapes);
var shape = DisposableCom.Create(shapes.ComObject.AddPicture(tmpFile, false, true, Type.Missing));
// Lock aspect ratio
if (_officeConfiguration.WordLockAspectRatio)
{
var shape = DisposableCom.Create(shapes.ComObject.AddPicture(tmpFile, false, true, Type.Missing));
// Lock aspect ratio
if (_officeConfiguration.WordLockAspectRatio)
{
shape.ComObject.LockAspectRatio = MsoTriState.msoTrue;
}
selection.ComObject.InsertAfter("\r\n");
selection.ComObject.MoveDown(WdUnits.wdLine, 1, Type.Missing);
return shape;
shape.ComObject.LockAspectRatio = MsoTriState.msoTrue;
}
selection.ComObject.InsertAfter("\r\n");
selection.ComObject.MoveDown(WdUnits.wdLine, 1, Type.Missing);
return shape;
}
/// <summary>
@ -113,36 +111,30 @@ namespace Greenshot.Addon.Office.OfficeExport
/// <returns></returns>
public IEnumerable<string> GetWordDocuments()
{
using (var wordApplication = GetWordApplication())
using var wordApplication = GetWordApplication();
if (wordApplication == null)
{
if (wordApplication == null)
yield break;
}
using var documents = DisposableCom.Create(wordApplication.ComObject.Documents);
for (int i = 1; i <= documents.ComObject.Count; i++)
{
using var document = DisposableCom.Create(documents.ComObject[i]);
if (document.ComObject.ReadOnly)
{
yield break;
continue;
}
using (var documents = DisposableCom.Create(wordApplication.ComObject.Documents))
if (IsAfter2003())
{
for (int i = 1; i <= documents.ComObject.Count; i++)
if (document.ComObject.Final)
{
using (var document = DisposableCom.Create(documents.ComObject[i]))
{
if (document.ComObject.ReadOnly)
{
continue;
}
if (IsAfter2003())
{
if (document.ComObject.Final)
{
continue;
}
}
using (var activeWindow = DisposableCom.Create(document.ComObject.ActiveWindow))
{
yield return activeWindow.ComObject.Caption;
}
}
continue;
}
}
using var activeWindow = DisposableCom.Create(document.ComObject.ActiveWindow);
yield return activeWindow.ComObject.Caption;
}
}
@ -177,20 +169,15 @@ namespace Greenshot.Addon.Office.OfficeExport
{
return false;
}
using (var documents = DisposableCom.Create(wordApplication.ComObject.Documents))
using var documents = DisposableCom.Create(wordApplication.ComObject.Documents);
for (int i = 1; i <= documents.ComObject.Count; i++)
{
for (int i = 1; i <= documents.ComObject.Count; i++)
using var wordDocument = DisposableCom.Create((_Document)documents.ComObject[i]);
using var activeWindow = DisposableCom.Create(wordDocument.ComObject.ActiveWindow);
if (activeWindow.ComObject.Caption.StartsWith(wordCaption))
{
using (var wordDocument = DisposableCom.Create((_Document)documents.ComObject[i]))
{
using (var activeWindow = DisposableCom.Create(wordDocument.ComObject.ActiveWindow))
{
if (activeWindow.ComObject.Caption.StartsWith(wordCaption))
{
return InsertIntoExistingDocument(wordApplication, wordDocument, tmpFile, null, null);
}
}
}
return InsertIntoExistingDocument(wordApplication, wordDocument, tmpFile, null, null);
}
}
}
@ -219,81 +206,72 @@ namespace Greenshot.Addon.Office.OfficeExport
{
Log.Warn().WriteLine(ex);
}
using (var selection = DisposableCom.Create(wordApplication.ComObject.Selection))
using var selection = DisposableCom.Create(wordApplication.ComObject.Selection);
if (selection == null)
{
if (selection == null)
{
Log.Info().WriteLine("No selection to insert {0} into found.", tmpFile);
return false;
}
// Add Picture
using (var shape = AddPictureToSelection(selection, tmpFile))
{
if (!string.IsNullOrEmpty(address))
{
object screentip = Type.Missing;
if (!string.IsNullOrEmpty(tooltip))
{
screentip = tooltip;
}
try
{
using (var hyperlinks = DisposableCom.Create(wordDocument.ComObject.Hyperlinks))
{
hyperlinks.ComObject.Add(shape, screentip, Type.Missing, screentip, Type.Missing, Type.Missing);
}
}
catch (Exception e)
{
Log.Warn().WriteLine("Couldn't add hyperlink for image: {0}", e.Message);
}
}
}
try
{
using (var activeWindow = DisposableCom.Create(wordDocument.ComObject.ActiveWindow))
{
activeWindow.ComObject.Activate();
using (var activePane = DisposableCom.Create(activeWindow.ComObject.ActivePane))
{
using (var view = DisposableCom.Create(activePane.ComObject.View))
{
view.ComObject.Zoom.Percentage = 100;
}
}
}
}
catch (Exception e)
{
if (e.InnerException != null)
{
Log.Warn().WriteLine("Couldn't set zoom to 100, error: {0}", e.InnerException.Message);
}
else
{
Log.Warn().WriteLine("Couldn't set zoom to 100, error: {0}", e.Message);
}
}
try
{
wordApplication.ComObject.Activate();
// ReSharper disable once EmptyGeneralCatchClause
}
catch (Exception ex)
{
Log.Warn().WriteLine(ex);
}
try
{
wordDocument.ComObject.Activate();
// ReSharper disable once EmptyGeneralCatchClause
}
catch (Exception ex)
{
Log.Warn().WriteLine(ex);
}
return true;
Log.Info().WriteLine("No selection to insert {0} into found.", tmpFile);
return false;
}
// Add Picture
using (var shape = AddPictureToSelection(selection, tmpFile))
{
if (!string.IsNullOrEmpty(address))
{
object screentip = Type.Missing;
if (!string.IsNullOrEmpty(tooltip))
{
screentip = tooltip;
}
try
{
using var hyperlinks = DisposableCom.Create(wordDocument.ComObject.Hyperlinks);
hyperlinks.ComObject.Add(shape, screentip, Type.Missing, screentip, Type.Missing, Type.Missing);
}
catch (Exception e)
{
Log.Warn().WriteLine("Couldn't add hyperlink for image: {0}", e.Message);
}
}
}
try
{
using var activeWindow = DisposableCom.Create(wordDocument.ComObject.ActiveWindow);
activeWindow.ComObject.Activate();
using var activePane = DisposableCom.Create(activeWindow.ComObject.ActivePane);
using var view = DisposableCom.Create(activePane.ComObject.View);
view.ComObject.Zoom.Percentage = 100;
}
catch (Exception e)
{
if (e.InnerException != null)
{
Log.Warn().WriteLine("Couldn't set zoom to 100, error: {0}", e.InnerException.Message);
}
else
{
Log.Warn().WriteLine("Couldn't set zoom to 100, error: {0}", e.Message);
}
}
try
{
wordApplication.ComObject.Activate();
// ReSharper disable once EmptyGeneralCatchClause
}
catch (Exception ex)
{
Log.Warn().WriteLine(ex);
}
try
{
wordDocument.ComObject.Activate();
// ReSharper disable once EmptyGeneralCatchClause
}
catch (Exception ex)
{
Log.Warn().WriteLine(ex);
}
return true;
}
/// <summary>
@ -304,76 +282,64 @@ namespace Greenshot.Addon.Office.OfficeExport
/// <param name="tooltip">string</param>
public void InsertIntoNewDocument(string tmpFile, string address, string tooltip)
{
using (var wordApplication = GetOrCreateWordApplication())
using var wordApplication = GetOrCreateWordApplication();
if (wordApplication == null)
{
if (wordApplication == null)
return;
}
wordApplication.ComObject.Visible = true;
wordApplication.ComObject.Activate();
// Create new Document
object template = string.Empty;
object newTemplate = false;
object documentType = 0;
object documentVisible = true;
using var documents = DisposableCom.Create(wordApplication.ComObject.Documents);
using var wordDocument = DisposableCom.Create(documents.ComObject.Add(template, newTemplate, documentType, documentVisible));
using (var selection = DisposableCom.Create(wordApplication.ComObject.Selection))
{
// Add Picture
using var shape = AddPictureToSelection(selection, tmpFile);
if (!string.IsNullOrEmpty(address))
{
return;
}
wordApplication.ComObject.Visible = true;
wordApplication.ComObject.Activate();
// Create new Document
object template = string.Empty;
object newTemplate = false;
object documentType = 0;
object documentVisible = true;
using (var documents = DisposableCom.Create(wordApplication.ComObject.Documents))
{
using (var wordDocument = DisposableCom.Create(documents.ComObject.Add(template, newTemplate, documentType, documentVisible)))
object screentip = Type.Missing;
if (!string.IsNullOrEmpty(tooltip))
{
using (var selection = DisposableCom.Create(wordApplication.ComObject.Selection))
screentip = tooltip;
}
try
{
using var hyperlinks = DisposableCom.Create(wordDocument.ComObject.Hyperlinks);
using (DisposableCom.Create(hyperlinks.ComObject.Add(shape, screentip, Type.Missing, screentip, Type.Missing, Type.Missing)))
{
// Add Picture
using (var shape = AddPictureToSelection(selection, tmpFile))
{
if (!string.IsNullOrEmpty(address))
{
object screentip = Type.Missing;
if (!string.IsNullOrEmpty(tooltip))
{
screentip = tooltip;
}
try
{
using (var hyperlinks = DisposableCom.Create(wordDocument.ComObject.Hyperlinks))
{
using (DisposableCom.Create(hyperlinks.ComObject.Add(shape, screentip, Type.Missing, screentip, Type.Missing, Type.Missing)))
{
// Do nothing
}
}
}
catch (Exception e)
{
Log.Warn().WriteLine("Couldn't add hyperlink for image: {0}", e.Message);
}
}
}
}
try
{
wordDocument.ComObject.Activate();
// ReSharper disable once EmptyGeneralCatchClause
}
catch (Exception ex)
{
Log.Warn().WriteLine(ex);
}
try
{
using (var activeWindow = DisposableCom.Create(wordDocument.ComObject.ActiveWindow))
{
activeWindow.ComObject.Activate();
}
// ReSharper disable once EmptyGeneralCatchClause
}
catch (Exception ex)
{
Log.Warn().WriteLine(ex);
// Do nothing
}
}
catch (Exception e)
{
Log.Warn().WriteLine("Couldn't add hyperlink for image: {0}", e.Message);
}
}
}
try
{
wordDocument.ComObject.Activate();
// ReSharper disable once EmptyGeneralCatchClause
}
catch (Exception ex)
{
Log.Warn().WriteLine(ex);
}
try
{
using var activeWindow = DisposableCom.Create(wordDocument.ComObject.ActiveWindow);
activeWindow.ComObject.Activate();
// ReSharper disable once EmptyGeneralCatchClause
}
catch (Exception ex)
{
Log.Warn().WriteLine(ex);
}
}
/// <summary>

View file

@ -126,10 +126,8 @@ namespace Greenshot.Addon.OneDrive
get
{
// TODO: Optimize this by caching
using (var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "onedrive.png"))
{
return BitmapHelper.FromStream(bitmapStream);
}
using var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "onedrive.png");
return BitmapHelper.FromStream(bitmapStream);
}
}
@ -188,11 +186,9 @@ namespace Greenshot.Addon.OneDrive
if (_oneDriveConfiguration.AfterUploadLinkToClipBoard)
{
using (var clipboardAccessToken = ClipboardNative.Access())
{
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(response.AbsoluteUri);
}
using var clipboardAccessToken = ClipboardNative.Access();
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(response.AbsoluteUri);
}
return response;
@ -227,17 +223,13 @@ namespace Greenshot.Addon.OneDrive
localBehaviour.UploadProgress = percent => { Execute.OnUIThread(() => progress.Report((int)(percent * 100))); };
}
var oauthHttpBehaviour = OAuth2HttpBehaviourFactory.Create(oAuth2Settings, localBehaviour);
using (var imageStream = new MemoryStream())
{
surfaceToUpload.WriteToStream(imageStream, CoreConfiguration, _oneDriveConfiguration);
imageStream.Position = 0;
using (var content = new StreamContent(imageStream))
{
content.Headers.Add("Content-Type", surfaceToUpload.GenerateMimeType(CoreConfiguration, _oneDriveConfiguration));
oauthHttpBehaviour.MakeCurrent();
return await uploadUri.PutAsync<OneDriveUploadResponse>(content, token);
}
}
using var imageStream = new MemoryStream();
surfaceToUpload.WriteToStream(imageStream, CoreConfiguration, _oneDriveConfiguration);
imageStream.Position = 0;
using var content = new StreamContent(imageStream);
content.Headers.Add("Content-Type", surfaceToUpload.GenerateMimeType(CoreConfiguration, _oneDriveConfiguration));
oauthHttpBehaviour.MakeCurrent();
return await uploadUri.PutAsync<OneDriveUploadResponse>(content, token);
}
private async Task<OneDriveGetLinkResponse> CreateSharableLinkAync(OAuth2Settings oAuth2Settings,

View file

@ -185,12 +185,10 @@ namespace Greenshot.Addon.Photobucket
public override IBitmapWithNativeSupport DisplayIcon
{
get
{
{
// TODO: Optimize this
using (var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "photobucket-logo.png"))
{
return BitmapHelper.FromStream(bitmapStream);
}
using var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "photobucket-logo.png");
return BitmapHelper.FromStream(bitmapStream);
}
}
@ -295,28 +293,26 @@ namespace Greenshot.Addon.Photobucket
{
surfaceToUpload.WriteToStream(imageStream, CoreConfiguration, _photobucketConfiguration);
imageStream.Position = 0;
using (var streamContent = new StreamContent(imageStream))
using var streamContent = new StreamContent(imageStream);
streamContent.Headers.ContentType = new MediaTypeHeaderValue(surfaceToUpload.GenerateMimeType(CoreConfiguration, _photobucketConfiguration));
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
streamContent.Headers.ContentType = new MediaTypeHeaderValue(surfaceToUpload.GenerateMimeType(CoreConfiguration, _photobucketConfiguration));
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"uploadfile\"",
FileName = "\"" + filename + "\""
};
Name = "\"uploadfile\"",
FileName = "\"" + filename + "\""
};
HttpBehaviour.Current.SetConfig(new HttpRequestMessageConfiguration
{
Properties = signedParameters
});
try
{
responseString = await uploadUri.PostAsync<string>(streamContent, token);
}
catch (Exception ex)
{
Log.Error().WriteLine(ex, "Error uploading to Photobucket.");
throw;
}
HttpBehaviour.Current.SetConfig(new HttpRequestMessageConfiguration
{
Properties = signedParameters
});
try
{
responseString = await uploadUri.PostAsync<string>(streamContent, token);
}
catch (Exception ex)
{
Log.Error().WriteLine(ex, "Error uploading to Photobucket.");
throw;
}
}

View file

@ -145,21 +145,17 @@ namespace Greenshot.Addon.Tfs
var filename = surface.GenerateFilename(_coreConfiguration, _tfsConfiguration);
var attachmentUri = apiUri.AppendSegments("wit", "attachments").ExtendQuery("fileName", filename);
using (var imageStream = new MemoryStream())
using var imageStream = new MemoryStream();
surface.WriteToStream(imageStream, _coreConfiguration, _tfsConfiguration);
imageStream.Position = 0;
using var content = new StreamContent(imageStream);
content.SetContentType("application/octet-stream");
var createAttachmentresult = await client.PostAsync<HttpResponse<CreateAttachmentResult, string>>(attachmentUri, content).ConfigureAwait(false);
if (createAttachmentresult.HasError)
{
surface.WriteToStream(imageStream, _coreConfiguration, _tfsConfiguration);
imageStream.Position = 0;
using (var content = new StreamContent(imageStream))
{
content.SetContentType("application/octet-stream");
var createAttachmentresult = await client.PostAsync<HttpResponse<CreateAttachmentResult, string>>(attachmentUri, content).ConfigureAwait(false);
if (createAttachmentresult.HasError)
{
throw new Exception(createAttachmentresult.ErrorResponse);
}
return createAttachmentresult.Response;
}
throw new Exception(createAttachmentresult.ErrorResponse);
}
return createAttachmentresult.Response;
}
/// <summary>

View file

@ -165,10 +165,8 @@ namespace Greenshot.Addon.Tfs
get
{
// TODO: Optimize this by using a cache
using (var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "vsts.png"))
{
return BitmapHelper.FromStream(bitmapStream);
}
using var bitmapStream = _resourceProvider.ResourceAsStream(GetType().Assembly, "vsts.png");
return BitmapHelper.FromStream(bitmapStream);
}
}
@ -224,11 +222,9 @@ namespace Greenshot.Addon.Tfs
if (_tfsConfiguration.AfterUploadLinkToClipBoard)
{
using (var clipboardAccessToken = ClipboardNative.Access())
{
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(response.AbsoluteUri);
}
using var clipboardAccessToken = ClipboardNative.Access();
clipboardAccessToken.ClearContents();
clipboardAccessToken.SetAsUrl(response.AbsoluteUri);
}
return response;

View file

@ -67,19 +67,14 @@ namespace Greenshot.Addons.Animation
/// </summary>
protected double EasingValue
{
get
{
switch (EasingMode)
{
case EasingModes.EaseOut:
return Easing.EaseOut(CurrentFrameNr / (double) Frames, EasingType);
case EasingModes.EaseInOut:
return Easing.EaseInOut(CurrentFrameNr / (double) Frames, EasingType);
default:
return Easing.EaseIn(CurrentFrameNr / (double) Frames, EasingType);
}
}
}
get =>
EasingMode switch
{
EasingModes.EaseOut => Easing.EaseOut(CurrentFrameNr / (double) Frames, EasingType),
EasingModes.EaseInOut => Easing.EaseInOut(CurrentFrameNr / (double) Frames, EasingType),
_ => Easing.EaseIn(CurrentFrameNr / (double) Frames, EasingType)
};
}
/// <summary>
/// Final animation value, this is including the legs

View file

@ -47,27 +47,18 @@ namespace Greenshot.Addons.Animation
/// <param name="linearStep">double</param>
/// <param name="type">EasingTypes</param>
/// <returns>double</returns>
public static double EaseIn(double linearStep, EasingTypes type)
{
switch (type)
{
case EasingTypes.Step:
return linearStep < 0.5 ? 0 : 1;
case EasingTypes.Linear:
return linearStep;
case EasingTypes.Sine:
return EaseSine.EaseIn(linearStep);
case EasingTypes.Quadratic:
return EasePower.EaseIn(linearStep, 2);
case EasingTypes.Cubic:
return EasePower.EaseIn(linearStep, 3);
case EasingTypes.Quartic:
return EasePower.EaseIn(linearStep, 4);
case EasingTypes.Quintic:
return EasePower.EaseIn(linearStep, 5);
}
throw new NotImplementedException();
}
public static double EaseIn(double linearStep, EasingTypes type) =>
type switch
{
EasingTypes.Step => (linearStep < 0.5 ? 0 : 1),
EasingTypes.Linear => linearStep,
EasingTypes.Sine => EaseSine.EaseIn(linearStep),
EasingTypes.Quadratic => EasePower.EaseIn(linearStep, 2),
EasingTypes.Cubic => EasePower.EaseIn(linearStep, 3),
EasingTypes.Quartic => EasePower.EaseIn(linearStep, 4),
EasingTypes.Quintic => EasePower.EaseIn(linearStep, 5),
_ => throw new NotImplementedException()
};
/// <summary>
/// Apply ease in-out
@ -87,54 +78,36 @@ namespace Greenshot.Addons.Animation
/// <param name="linearStep">double</param>
/// <param name="type">EasingTypes</param>
/// <returns>double</returns>
public static double EaseInOut(double linearStep, EasingTypes type)
{
switch (type)
{
case EasingTypes.Step:
return linearStep < 0.5 ? 0 : 1;
case EasingTypes.Linear:
return linearStep;
case EasingTypes.Sine:
return EaseSine.EaseInOut(linearStep);
case EasingTypes.Quadratic:
return EasePower.EaseInOut(linearStep, 2);
case EasingTypes.Cubic:
return EasePower.EaseInOut(linearStep, 3);
case EasingTypes.Quartic:
return EasePower.EaseInOut(linearStep, 4);
case EasingTypes.Quintic:
return EasePower.EaseInOut(linearStep, 5);
}
throw new NotImplementedException();
}
public static double EaseInOut(double linearStep, EasingTypes type) =>
type switch
{
EasingTypes.Step => (linearStep < 0.5 ? 0 : 1),
EasingTypes.Linear => linearStep,
EasingTypes.Sine => EaseSine.EaseInOut(linearStep),
EasingTypes.Quadratic => EasePower.EaseInOut(linearStep, 2),
EasingTypes.Cubic => EasePower.EaseInOut(linearStep, 3),
EasingTypes.Quartic => EasePower.EaseInOut(linearStep, 4),
EasingTypes.Quintic => EasePower.EaseInOut(linearStep, 5),
_ => throw new NotImplementedException()
};
/// <summary>
/// <summary>
/// Apply easy out
/// </summary>
/// <param name="linearStep">double</param>
/// <param name="type">EasingTypes</param>
/// <returns>double</returns>
public static double EaseOut(double linearStep, EasingTypes type)
{
switch (type)
{
case EasingTypes.Step:
return linearStep < 0.5 ? 0 : 1;
case EasingTypes.Linear:
return linearStep;
case EasingTypes.Sine:
return EaseSine.EaseOut(linearStep);
case EasingTypes.Quadratic:
return EasePower.EaseOut(linearStep, 2);
case EasingTypes.Cubic:
return EasePower.EaseOut(linearStep, 3);
case EasingTypes.Quartic:
return EasePower.EaseOut(linearStep, 4);
case EasingTypes.Quintic:
return EasePower.EaseOut(linearStep, 5);
}
throw new NotImplementedException();
}
}
public static double EaseOut(double linearStep, EasingTypes type) =>
type switch
{
EasingTypes.Step => (linearStep < 0.5 ? 0 : 1),
EasingTypes.Linear => linearStep,
EasingTypes.Sine => EaseSine.EaseOut(linearStep),
EasingTypes.Quadratic => EasePower.EaseOut(linearStep, 2),
EasingTypes.Cubic => EasePower.EaseOut(linearStep, 3),
EasingTypes.Quartic => EasePower.EaseOut(linearStep, 4),
EasingTypes.Quintic => EasePower.EaseOut(linearStep, 5),
_ => throw new NotImplementedException()
};
}
}

View file

@ -81,13 +81,11 @@ namespace Greenshot.Addons.Controls
get
{
if (_vRefresh == 0)
{
// get te hDC of the desktop to get the VREFRESH
using (var desktopHandle = SafeWindowDcHandle.FromDesktop())
{
_vRefresh = Gdi32Api.GetDeviceCaps(desktopHandle, DeviceCaps.VREFRESH);
}
}
{
// get te hDC of the desktop to get the VREFRESH
using var desktopHandle = SafeWindowDcHandle.FromDesktop();
_vRefresh = Gdi32Api.GetDeviceCaps(desktopHandle, DeviceCaps.VREFRESH);
}
// A vertical refresh rate value of 0 or 1 represents the display hardware's default refresh rate.
// As there is currently no know way to get the default, we guess it.
if (_vRefresh <= 1)

View file

@ -101,20 +101,18 @@ namespace Greenshot.Addons.Controls
/// <param name="screenCoordinates">Point with the coordinates</param>
/// <returns>Color at the specified screenCoordinates</returns>
private static Color GetPixelColor(Point screenCoordinates)
{
using (var screenDc = SafeWindowDcHandle.FromDesktop())
{
try
{
var pixel = Gdi32Api.GetPixel(screenDc, screenCoordinates.X, screenCoordinates.Y);
var color = Color.FromArgb(255, (int) (pixel & 0xFF), (int) (pixel & 0xFF00) >> 8, (int) (pixel & 0xFF0000) >> 16);
return color;
}
catch (Exception)
{
return Color.Empty;
}
}
}
{
using var screenDc = SafeWindowDcHandle.FromDesktop();
try
{
var pixel = Gdi32Api.GetPixel(screenDc, screenCoordinates.X, screenCoordinates.Y);
var color = Color.FromArgb(255, (int) (pixel & 0xFF), (int) (pixel & 0xFF00) >> 8, (int) (pixel & 0xFF0000) >> 16);
return color;
}
catch (Exception)
{
return Color.Empty;
}
}
}
}

View file

@ -132,6 +132,7 @@ namespace Greenshot.Addons.Core
_safeDibSectionHandle.Dispose();
_safeCompatibleDcHandle.Dispose();
_desktopDcHandle.Dispose();
_bitmap.Dispose();
}
}

View file

@ -122,26 +122,24 @@ EndSelection:<<<<<<<4
try
{
User32Api.GetWindowThreadProcessId(hWnd, out var pid);
using (var me = Process.GetCurrentProcess())
using (var ownerProcess = Process.GetProcessById(pid))
{
// Exclude myself
if (me.Id != ownerProcess.Id)
{
// Get Process Name
owner = ownerProcess.ProcessName;
// Try to get the starting Process Filename, this might fail.
try
{
owner = ownerProcess.Modules[0].FileName;
}
catch (Exception)
{
// Ignore
}
}
}
}
using var me = Process.GetCurrentProcess();
using var ownerProcess = Process.GetProcessById(pid);
// Exclude myself
if (me.Id != ownerProcess.Id)
{
// Get Process Name
owner = ownerProcess.ProcessName;
// Try to get the starting Process Filename, this might fail.
try
{
owner = ownerProcess.Modules[0].FileName;
}
catch (Exception)
{
// Ignore
}
}
}
catch (Exception e)
{
Log.Warn().WriteLine(e, "Non critical error: Couldn't get clipboard process, trying to use the title.");
@ -483,18 +481,16 @@ EndSelection:<<<<<<<4
var fileHeader = BitmapFileHeader.Create(infoHeader);
var fileHeaderBytes = BinaryStructHelper.ToByteArray(fileHeader);
using (var bitmapStream = new MemoryStream())
{
bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize);
bitmapStream.Write(dibBuffer, 0, dibBuffer.Length);
bitmapStream.Seek(0, SeekOrigin.Begin);
var image = BitmapHelper.FromStream(bitmapStream);
if (image != null)
{
return image;
}
}
}
using var bitmapStream = new MemoryStream();
bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize);
bitmapStream.Write(dibBuffer, 0, dibBuffer.Length);
bitmapStream.Seek(0, SeekOrigin.Begin);
var image = BitmapHelper.FromStream(bitmapStream);
if (image != null)
{
return image;
}
}
else
{
Log.Info().WriteLine("Using special DIBV5 / Format17 format reader");

View file

@ -326,8 +326,9 @@ namespace Greenshot.Addons.Core.Credentials
info.pszCaptionText = Caption;
info.pszMessageText = Message;
if (Banner != null)
{
info.hbmBanner = new Bitmap(Banner, ValidBannerWidth, ValidBannerHeight).GetHbitmap();
{
using var bitmap = new Bitmap(Banner, ValidBannerWidth, ValidBannerHeight);
info.hbmBanner = bitmap.GetHbitmap();
}
info.cbSize = Marshal.SizeOf(info);
return info;
@ -380,36 +381,21 @@ namespace Greenshot.Addons.Core.Credentials
/// <summary>Returns a DialogResult from the specified code.</summary>
/// <param name="code">The credential return code.</param>
private DialogResult GetDialogResult(CredUiReturnCodes code)
{
DialogResult result;
switch (code)
{
case CredUiReturnCodes.NoError:
result = DialogResult.OK;
break;
case CredUiReturnCodes.ErrorCancelled:
result = DialogResult.Cancel;
break;
case CredUiReturnCodes.ErrorNoSuchLogonSession:
throw new ApplicationException("No such logon session.");
case CredUiReturnCodes.ErrorNotFound:
throw new ApplicationException("Not found.");
case CredUiReturnCodes.ErrorInvalidAccountName:
throw new ApplicationException("Invalid account name.");
case CredUiReturnCodes.ErrorInsufficientBuffer:
throw new ApplicationException("Insufficient buffer.");
case CredUiReturnCodes.ErrorInvalidParameter:
throw new ApplicationException("Invalid parameter.");
case CredUiReturnCodes.ErrorInvalidFlags:
throw new ApplicationException("Invalid flags.");
default:
throw new ApplicationException("Unknown credential result encountered.");
}
return result;
}
private DialogResult GetDialogResult(CredUiReturnCodes code) =>
code switch
{
CredUiReturnCodes.NoError => DialogResult.OK,
CredUiReturnCodes.ErrorCancelled => DialogResult.Cancel,
CredUiReturnCodes.ErrorNoSuchLogonSession => throw new ApplicationException("No such logon session."),
CredUiReturnCodes.ErrorNotFound => throw new ApplicationException("Not found."),
CredUiReturnCodes.ErrorInvalidAccountName => throw new ApplicationException("Invalid account name."),
CredUiReturnCodes.ErrorInsufficientBuffer => throw new ApplicationException("Insufficient buffer."),
CredUiReturnCodes.ErrorInvalidParameter => throw new ApplicationException("Invalid parameter."),
CredUiReturnCodes.ErrorInvalidFlags => throw new ApplicationException("Invalid flags."),
_ => throw new ApplicationException("Unknown credential result encountered.")
};
/// <summary>
/// <summary>
/// http://www.pinvoke.net/default.aspx/credui.CredUIPromptForCredentialsW
/// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthn/security/creduipromptforcredentials.asp
/// </summary>

View file

@ -56,12 +56,10 @@ namespace Greenshot.Addons.Core
/// </summary>
/// <returns>bool</returns>
public static bool HasMapi()
{
using (var key = Registry.LocalMachine.OpenSubKey(MapiLocationKey, false))
{
return key != null && "1".Equals(key.GetValue(MapiKey, "0"));
}
}
{
using var key = Registry.LocalMachine.OpenSubKey(MapiLocationKey, false);
return key != null && "1".Equals(key.GetValue(MapiKey, "0"));
}
/// <summary>
/// Get the path of Outlook from the registry

View file

@ -67,12 +67,10 @@ namespace Greenshot.Addons.Core
UseShellExecute = true
};
// Start the explorer process and select the file
using (var explorer = Process.Start(processStartInfo))
{
explorer?.WaitForInputIdle(500);
return true;
}
}
using var explorer = Process.Start(processStartInfo);
explorer?.WaitForInputIdle(500);
return true;
}
}
catch (Exception ex)
{

View file

@ -96,7 +96,7 @@ namespace Greenshot.Addons.Core
// Set the text
var byteString = Encoding.ASCII.GetBytes(text + " ");
// Set Zero byte for String end.
byteString[byteString.Length - 1] = 0;
byteString[^1] = 0;
propertyItem.Value = byteString;
propertyItem.Len = text.Length + 1;
}
@ -128,7 +128,7 @@ namespace Greenshot.Addons.Core
if (CoreConfiguration.OutputFilePromptQuality)
{
// TODO: Use factory
var qualityDialog = new QualityDialog(outputSettings, CoreConfiguration, GreenshotLanguage);
using var qualityDialog = new QualityDialog(outputSettings, CoreConfiguration, GreenshotLanguage);
qualityDialog.ShowDialog();
}
// TODO: For now we always overwrite, should be changed
@ -309,25 +309,19 @@ namespace Greenshot.Addons.Core
}
var imageStream = new MemoryStream();
if (bitmap.Width == size && bitmap.Height == size)
{
using (var clonedImage = bitmap.CloneBitmap(PixelFormat.Format32bppArgb))
{
clonedImage.NativeBitmap.Save(imageStream, ImageFormat.Png);
imageSizes.Add(new Size(size, size));
}
}
{
using var clonedImage = bitmap.CloneBitmap(PixelFormat.Format32bppArgb);
clonedImage.NativeBitmap.Save(imageStream, ImageFormat.Png);
imageSizes.Add(new Size(size, size));
}
else
{
// Resize to the specified size, first make sure the image is 32bpp
using (var clonedImage = bitmap.CloneBitmap(PixelFormat.Format32bppArgb))
{
using (var resizedImage = clonedImage.Resize(true, true, Color.Empty, size, size, null))
{
resizedImage.NativeBitmap.Save(imageStream, ImageFormat.Png);
imageSizes.Add(resizedImage.Size);
}
}
}
{
// Resize to the specified size, first make sure the image is 32bpp
using var clonedImage = bitmap.CloneBitmap(PixelFormat.Format32bppArgb);
using var resizedImage = clonedImage.Resize(true, true, Color.Empty, size, size, null);
resizedImage.NativeBitmap.Save(imageStream, ImageFormat.Png);
imageSizes.Add(resizedImage.Size);
}
imageStream.Seek(0, SeekOrigin.Begin);
encodedImages.Add(imageStream);
@ -395,13 +389,11 @@ namespace Greenshot.Addons.Core
Log.Info().WriteLine("Greenshot file format: {0}", greenshotMarker);
const int filesizeLocation = 8 + markerSize;
surfaceFileStream.Seek(-filesizeLocation, SeekOrigin.End);
using (var reader = new BinaryReader(surfaceFileStream))
{
var bytesWritten = reader.ReadInt64();
surfaceFileStream.Seek(-(bytesWritten + filesizeLocation), SeekOrigin.End);
returnSurface.LoadElementsFromStream(surfaceFileStream);
}
}
using var reader = new BinaryReader(surfaceFileStream);
var bytesWritten = reader.ReadInt64();
surfaceFileStream.Seek(-(bytesWritten + filesizeLocation), SeekOrigin.End);
returnSurface.LoadElementsFromStream(surfaceFileStream);
}
if (fileImage == null)
{
return returnSurface;
@ -566,20 +558,16 @@ namespace Greenshot.Addons.Core
// Output the surface elements, size and marker to the stream
if (outputSettings.Format == OutputFormats.greenshot)
{
using (var tmpStream = new MemoryStream())
{
var bytesWritten = surface.SaveElementsToStream(tmpStream);
using (var writer = new BinaryWriter(tmpStream))
{
writer.Write(bytesWritten);
var v = Assembly.GetExecutingAssembly().GetName().Version;
var marker = Encoding.ASCII.GetBytes($"Greenshot{v.Major:00}.{v.Minor:00}");
writer.Write(marker);
tmpStream.WriteTo(stream);
}
}
}
{
using var tmpStream = new MemoryStream();
var bytesWritten = surface.SaveElementsToStream(tmpStream);
using var writer = new BinaryWriter(tmpStream);
writer.Write(bytesWritten);
var v = Assembly.GetExecutingAssembly().GetName().Version;
var marker = Encoding.ASCII.GetBytes($"Greenshot{v.Major:00}.{v.Minor:00}");
writer.Write(marker);
tmpStream.WriteTo(stream);
}
}
finally
{
@ -630,28 +618,26 @@ namespace Greenshot.Addons.Core
RedirectStandardError = true,
UseShellExecute = true
};
using (var process = Process.Start(processStartInfo))
{
if (process != null)
{
process.WaitForExit();
if (process.ExitCode == 0)
{
if (Log.IsDebugEnabled())
{
Log.Debug().WriteLine("File size after processing {0}", new FileInfo(tmpFileName).Length);
Log.Debug().WriteLine("Reading back tmp file: {0}", tmpFileName);
}
var processedImage = File.ReadAllBytes(tmpFileName);
targetStream.Write(processedImage, 0, processedImage.Length);
return true;
}
Log.Error().WriteLine("Error while processing PNG image: {0}", process.ExitCode);
Log.Error().WriteLine("Output: {0}", process.StandardOutput.ReadToEnd());
Log.Error().WriteLine("Error: {0}", process.StandardError.ReadToEnd());
}
}
}
using var process = Process.Start(processStartInfo);
if (process != null)
{
process.WaitForExit();
if (process.ExitCode == 0)
{
if (Log.IsDebugEnabled())
{
Log.Debug().WriteLine("File size after processing {0}", new FileInfo(tmpFileName).Length);
Log.Debug().WriteLine("Reading back tmp file: {0}", tmpFileName);
}
var processedImage = File.ReadAllBytes(tmpFileName);
targetStream.Write(processedImage, 0, processedImage.Length);
return true;
}
Log.Error().WriteLine("Error while processing PNG image: {0}", process.ExitCode);
Log.Error().WriteLine("Output: {0}", process.StandardOutput.ReadToEnd());
Log.Error().WriteLine("Error: {0}", process.StandardError.ReadToEnd());
}
}
catch (Exception e)
{
Log.Error().WriteLine(e, "Error while processing PNG image: ");
@ -721,33 +707,31 @@ namespace Greenshot.Addons.Core
}
var isAlpha = Image.IsAlphaPixelFormat(bitmapToSave.PixelFormat);
if (outputSettings.ReduceColors || !isAlpha && CoreConfiguration.OutputFileAutoReduceColors)
{
using (var quantizer = new WuQuantizer(bitmapToSave))
{
var colorCount = quantizer.GetColorCount();
Log.Info().WriteLine("Image with format {0} has {1} colors", bitmapToSave.PixelFormat, colorCount);
if (!outputSettings.ReduceColors && colorCount >= 256)
{
return disposeImage;
}
try
{
Log.Info().WriteLine("Reducing colors on bitmap to 256.");
tmpBitmap = quantizer.GetQuantizedImage(CoreConfiguration.OutputFileReduceColorsTo);
if (disposeImage)
{
bitmapToSave.Dispose();
}
bitmapToSave = tmpBitmap;
// Make sure the "new" image is disposed
disposeImage = true;
}
catch (Exception e)
{
Log.Warn().WriteLine(e, "Error occurred while Quantizing the image, ignoring and using original. Error: ");
}
}
}
{
using var quantizer = new WuQuantizer(bitmapToSave);
var colorCount = quantizer.GetColorCount();
Log.Info().WriteLine("Image with format {0} has {1} colors", bitmapToSave.PixelFormat, colorCount);
if (!outputSettings.ReduceColors && colorCount >= 256)
{
return disposeImage;
}
try
{
Log.Info().WriteLine("Reducing colors on bitmap to 256.");
tmpBitmap = quantizer.GetQuantizedImage(CoreConfiguration.OutputFileReduceColorsTo);
if (disposeImage)
{
bitmapToSave.Dispose();
}
bitmapToSave = tmpBitmap;
// Make sure the "new" image is disposed
disposeImage = true;
}
catch (Exception e)
{
Log.Warn().WriteLine(e, "Error occurred while Quantizing the image, ignoring and using original. Error: ");
}
}
else if (isAlpha && !outputSettings.ReduceColors)
{
Log.Info().WriteLine("Skipping 'optional' color reduction as the image has alpha");
@ -837,14 +821,12 @@ namespace Greenshot.Addons.Core
// TODO: This should not be done here, remove this!!
if (copyPathToClipboard)
{
using (var clipboardAccessToken = ClipboardNative.Access())
{
clipboardAccessToken.ClearContents();
// TODO: File??
clipboardAccessToken.SetAsUnicodeString(fullPath);
}
}
{
using var clipboardAccessToken = ClipboardNative.Access();
clipboardAccessToken.ClearContents();
// TODO: File??
clipboardAccessToken.SetAsUnicodeString(fullPath);
}
}
/// <summary>

View file

@ -187,36 +187,34 @@ namespace Greenshot.Addons.Core
{
// Assume using it's own location
formLocation = windowRectangle.Location;
using (var workingArea = new Region(Screen.PrimaryScreen.Bounds))
using var workingArea = new Region(Screen.PrimaryScreen.Bounds);
// Find the screen where the window is and check if it fits
foreach (var screen in Screen.AllScreens)
{
// Find the screen where the window is and check if it fits
if (!Equals(screen, Screen.PrimaryScreen))
{
workingArea.Union(screen.Bounds);
}
}
// If the formLocation is not inside the visible area
if (!workingArea.AreRectangleCornersVisisble(windowRectangle))
{
// If none found we find the biggest screen
foreach (var screen in Screen.AllScreens)
{
if (!Equals(screen, Screen.PrimaryScreen))
var newWindowRectangle = new NativeRect(screen.WorkingArea.Location, windowRectangle.Size);
if (workingArea.AreRectangleCornersVisisble(newWindowRectangle))
{
workingArea.Union(screen.Bounds);
formLocation = screen.Bounds.Location;
doesCaptureFit = true;
break;
}
}
// If the formLocation is not inside the visible area
if (!workingArea.AreRectangleCornersVisisble(windowRectangle))
{
// If none found we find the biggest screen
foreach (var screen in Screen.AllScreens)
{
var newWindowRectangle = new NativeRect(screen.WorkingArea.Location, windowRectangle.Size);
if (workingArea.AreRectangleCornersVisisble(newWindowRectangle))
{
formLocation = screen.Bounds.Location;
doesCaptureFit = true;
break;
}
}
}
else
{
doesCaptureFit = true;
}
}
else
{
doesCaptureFit = true;
}
}
else if (!WindowsVersion.IsWindows8OrLater)
@ -251,13 +249,11 @@ namespace Greenshot.Addons.Core
if (!doesCaptureFit)
{
// if GDI is allowed.. (a screenshot won't be better than we comes if we continue)
using (var thisWindowProcess = Process.GetProcessById(interopWindow.GetProcessId()))
using var thisWindowProcess = Process.GetProcessById(interopWindow.GetProcessId());
if (!interopWindow.IsApp() && WindowCapture.IsGdiAllowed(thisWindowProcess))
{
if (!interopWindow.IsApp() && WindowCapture.IsGdiAllowed(thisWindowProcess))
{
// we return null which causes the capturing code to try another method.
return null;
}
// we return null which causes the capturing code to try another method.
return null;
}
}
}
@ -289,25 +285,21 @@ namespace Greenshot.Addons.Core
try
{
using (var whiteBitmap = WindowCapture.CaptureRectangle(captureRectangle))
using var whiteBitmap = WindowCapture.CaptureRectangle(captureRectangle);
// Apply a white color
tempForm.BackColor = Color.Black;
// Make sure everything is visible
tempForm.Refresh();
if (!interopWindow.IsApp())
{
// Apply a white color
tempForm.BackColor = Color.Black;
// Make sure everything is visible
tempForm.Refresh();
if (!interopWindow.IsApp())
{
// Make sure the application window is active, so the colors & buttons are right
// TODO: Await?
interopWindow.ToForegroundAsync();
}
// Make sure all changes are processed and visible
Application.DoEvents();
using (var blackBitmap = WindowCapture.CaptureRectangle(captureRectangle))
{
capturedBitmap = ApplyTransparency(blackBitmap, whiteBitmap);
}
// Make sure the application window is active, so the colors & buttons are right
// TODO: Await?
interopWindow.ToForegroundAsync();
}
// Make sure all changes are processed and visible
Application.DoEvents();
using var blackBitmap = WindowCapture.CaptureRectangle(captureRectangle);
capturedBitmap = ApplyTransparency(blackBitmap, whiteBitmap);
}
catch (Exception e)
{
@ -400,17 +392,15 @@ namespace Greenshot.Addons.Core
/// <param name="image">The bitmap to remove the corners from.</param>
private static void RemoveCorners(IBitmapWithNativeSupport image)
{
using (var fastBitmap = FastBitmapFactory.Create(image))
using var fastBitmap = FastBitmapFactory.Create(image);
for (var y = 0; y < CoreConfiguration.WindowCornerCutShape.Count; y++)
{
for (var y = 0; y < CoreConfiguration.WindowCornerCutShape.Count; y++)
for (var x = 0; x < CoreConfiguration.WindowCornerCutShape[y]; x++)
{
for (var x = 0; x < CoreConfiguration.WindowCornerCutShape[y]; x++)
{
fastBitmap.SetColorAt(x, y, ref _transparentColor);
fastBitmap.SetColorAt(image.Width - 1 - x, y, ref _transparentColor);
fastBitmap.SetColorAt(image.Width - 1 - x, image.Height - 1 - y, ref _transparentColor);
fastBitmap.SetColorAt(x, image.Height - 1 - y, ref _transparentColor);
}
fastBitmap.SetColorAt(x, y, ref _transparentColor);
fastBitmap.SetColorAt(image.Width - 1 - x, y, ref _transparentColor);
fastBitmap.SetColorAt(image.Width - 1 - x, image.Height - 1 - y, ref _transparentColor);
fastBitmap.SetColorAt(x, image.Height - 1 - y, ref _transparentColor);
}
}
}
@ -425,50 +415,46 @@ namespace Greenshot.Addons.Core
/// <returns>Bitmap with transparency</returns>
private static IBitmapWithNativeSupport ApplyTransparency(IBitmapWithNativeSupport blackBitmap, IBitmapWithNativeSupport whiteBitmap)
{
using (var targetBuffer = FastBitmapFactory.CreateEmpty(blackBitmap.Size, PixelFormat.Format32bppArgb, Color.Transparent))
using var targetBuffer = FastBitmapFactory.CreateEmpty(blackBitmap.Size, PixelFormat.Format32bppArgb, Color.Transparent);
targetBuffer.SetResolution(blackBitmap.HorizontalResolution, blackBitmap.VerticalResolution);
using (var blackBuffer = FastBitmapFactory.Create(blackBitmap))
{
targetBuffer.SetResolution(blackBitmap.HorizontalResolution, blackBitmap.VerticalResolution);
using (var blackBuffer = FastBitmapFactory.Create(blackBitmap))
using var whiteBuffer = FastBitmapFactory.Create(whiteBitmap);
for (var y = 0; y < blackBuffer.Height; y++)
{
using (var whiteBuffer = FastBitmapFactory.Create(whiteBitmap))
for (var x = 0; x < blackBuffer.Width; x++)
{
for (var y = 0; y < blackBuffer.Height; y++)
var c0 = blackBuffer.GetColorAt(x, y);
var c1 = whiteBuffer.GetColorAt(x, y);
// Calculate alpha as double in range 0-1
var alpha = c0.R - c1.R + 255;
if (alpha == 255)
{
for (var x = 0; x < blackBuffer.Width; x++)
{
var c0 = blackBuffer.GetColorAt(x, y);
var c1 = whiteBuffer.GetColorAt(x, y);
// Calculate alpha as double in range 0-1
var alpha = c0.R - c1.R + 255;
if (alpha == 255)
{
// Alpha == 255 means no change!
targetBuffer.SetColorAt(x, y, ref c0);
}
else if (alpha == 0)
{
// Complete transparency, use transparent pixel
targetBuffer.SetColorAt(x, y, ref _transparentColor);
}
else
{
// Calculate original color
var originalAlpha = (byte) Math.Min(255, alpha);
var alphaFactor = alpha / 255d;
//Log.Debug().WriteLine("Alpha {0} & c0 {1} & c1 {2}", alpha, c0, c1);
var originalRed = (byte) Math.Min(255, c0.R / alphaFactor);
var originalGreen = (byte) Math.Min(255, c0.G / alphaFactor);
var originalBlue = (byte) Math.Min(255, c0.B / alphaFactor);
var originalColor = Color.FromArgb(originalAlpha, originalRed, originalGreen, originalBlue);
//Color originalColor = Color.FromArgb(originalAlpha, originalRed, c0.G, c0.B);
targetBuffer.SetColorAt(x, y, ref originalColor);
}
}
// Alpha == 255 means no change!
targetBuffer.SetColorAt(x, y, ref c0);
}
else if (alpha == 0)
{
// Complete transparency, use transparent pixel
targetBuffer.SetColorAt(x, y, ref _transparentColor);
}
else
{
// Calculate original color
var originalAlpha = (byte) Math.Min(255, alpha);
var alphaFactor = alpha / 255d;
//Log.Debug().WriteLine("Alpha {0} & c0 {1} & c1 {2}", alpha, c0, c1);
var originalRed = (byte) Math.Min(255, c0.R / alphaFactor);
var originalGreen = (byte) Math.Min(255, c0.G / alphaFactor);
var originalBlue = (byte) Math.Min(255, c0.B / alphaFactor);
var originalColor = Color.FromArgb(originalAlpha, originalRed, originalGreen, originalBlue);
//Color originalColor = Color.FromArgb(originalAlpha, originalRed, c0.G, c0.B);
targetBuffer.SetColorAt(x, y, ref originalColor);
}
}
}
return targetBuffer.UnlockAndReturnBitmap();
}
return targetBuffer.UnlockAndReturnBitmap();
}
}
}

View file

@ -52,13 +52,11 @@ namespace Greenshot.Addons.Core
}
IFormatter formatter = new BinaryFormatter();
using (var stream = new MemoryStream())
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T) formatter.Deserialize(stream);
}
}
using var stream = new MemoryStream();
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T) formatter.Deserialize(stream);
}
/// <summary>
/// Clone the content from source to destination

View file

@ -116,10 +116,8 @@ namespace Greenshot.Addons.Core
// Set the location
capture.CursorLocation = new NativePoint(x, y);
using (var icon = Icon.FromHandle(safeIcon.DangerousGetHandle()))
{
capture.Cursor = icon;
}
using var icon = Icon.FromHandle(safeIcon.DangerousGetHandle());
capture.Cursor = icon;
}
}
return capture;
@ -305,121 +303,113 @@ namespace Greenshot.Addons.Core
}
// create a device context we can copy to
using (var safeCompatibleDcHandle = Gdi32Api.CreateCompatibleDC(desktopDcHandle))
using var safeCompatibleDcHandle = Gdi32Api.CreateCompatibleDC(desktopDcHandle);
// Check if the device context is there, if not throw an error with as much info as possible!
if (safeCompatibleDcHandle.IsInvalid)
{
// Check if the device context is there, if not throw an error with as much info as possible!
if (safeCompatibleDcHandle.IsInvalid)
// Get Exception before the error is lost
var exceptionToThrow = CreateCaptureException("CreateCompatibleDC", captureBounds);
// throw exception
throw exceptionToThrow;
}
// Create BitmapInfoHeader for CreateDIBSection
var bmi = BitmapInfoHeader.Create(captureBounds.Width, captureBounds.Height, 24);
// TODO: Enable when the function is available again
// Make sure the last error is set to 0
Win32.SetLastError(0);
// create a bitmap we can copy it to, using GetDeviceCaps to get the width/height
// the returned (out) IntPtr _ is not used for our purposes. It returns a pointer to the raw bits that make up the bitmap.
using var safeDibSectionHandle = Gdi32Api.CreateDIBSection(desktopDcHandle, ref bmi, DibColors.PalColors, out _, IntPtr.Zero, 0);
if (safeDibSectionHandle.IsInvalid)
{
// Get Exception before the error is lost
var exceptionToThrow = CreateCaptureException("CreateDIBSection", captureBounds);
exceptionToThrow.Data.Add("hdcDest", safeCompatibleDcHandle.DangerousGetHandle().ToInt32());
exceptionToThrow.Data.Add("hdcSrc", desktopDcHandle.DangerousGetHandle().ToInt32());
// Throw so people can report the problem
throw exceptionToThrow;
}
// select the bitmap object and store the old handle
using (safeCompatibleDcHandle.SelectObject(safeDibSectionHandle))
{
// bit-blt over (make copy)
// ReSharper disable once BitwiseOperatorOnEnumWithoutFlags
Gdi32Api.BitBlt(safeCompatibleDcHandle, 0, 0, captureBounds.Width, captureBounds.Height, desktopDcHandle, captureBounds.X, captureBounds.Y,
RasterOperations.SourceCopy | RasterOperations.CaptureBlt);
}
// get a .NET image object for it
// A suggestion for the "A generic error occurred in GDI+." E_FAIL/0x80004005 error is to re-try...
ExternalException exception = null;
for (var i = 0; i < 3; i++)
{
try
{
// Get Exception before the error is lost
var exceptionToThrow = CreateCaptureException("CreateCompatibleDC", captureBounds);
// throw exception
throw exceptionToThrow;
}
// Create BitmapInfoHeader for CreateDIBSection
var bmi = BitmapInfoHeader.Create(captureBounds.Width, captureBounds.Height, 24);
// TODO: Enable when the function is available again
// Make sure the last error is set to 0
Win32.SetLastError(0);
// create a bitmap we can copy it to, using GetDeviceCaps to get the width/height
// the returned (out) IntPtr _ is not used for our purposes. It returns a pointer to the raw bits that make up the bitmap.
using (var safeDibSectionHandle = Gdi32Api.CreateDIBSection(desktopDcHandle, ref bmi, DibColors.PalColors, out _, IntPtr.Zero, 0))
{
if (safeDibSectionHandle.IsInvalid)
// Collect all screens inside this capture
var screensInsideCapture = new List<Screen>();
foreach (var screen in Screen.AllScreens)
{
// Get Exception before the error is lost
var exceptionToThrow = CreateCaptureException("CreateDIBSection", captureBounds);
exceptionToThrow.Data.Add("hdcDest", safeCompatibleDcHandle.DangerousGetHandle().ToInt32());
exceptionToThrow.Data.Add("hdcSrc", desktopDcHandle.DangerousGetHandle().ToInt32());
// Throw so people can report the problem
throw exceptionToThrow;
}
// select the bitmap object and store the old handle
using (safeCompatibleDcHandle.SelectObject(safeDibSectionHandle))
{
// bit-blt over (make copy)
// ReSharper disable once BitwiseOperatorOnEnumWithoutFlags
Gdi32Api.BitBlt(safeCompatibleDcHandle, 0, 0, captureBounds.Width, captureBounds.Height, desktopDcHandle, captureBounds.X, captureBounds.Y,
RasterOperations.SourceCopy | RasterOperations.CaptureBlt);
}
// get a .NET image object for it
// A suggestion for the "A generic error occurred in GDI+." E_FAIL/0x80004005 error is to re-try...
ExternalException exception = null;
for (var i = 0; i < 3; i++)
{
try
if (screen.Bounds.IntersectsWith(captureBounds))
{
// Collect all screens inside this capture
var screensInsideCapture = new List<Screen>();
screensInsideCapture.Add(screen);
}
}
// Check all all screens are of an equal size
bool offscreenContent;
using (var captureRegion = new Region(captureBounds))
{
// Exclude every visible part
foreach (var screen in screensInsideCapture)
{
captureRegion.Exclude(screen.Bounds);
}
// If the region is not empty, we have "offscreenContent"
using var screenGraphics = Graphics.FromHwnd(User32Api.GetDesktopWindow());
offscreenContent = !captureRegion.IsEmpty(screenGraphics);
}
// Check if we need to have a transparent background, needed for offscreen content
if (offscreenContent)
{
using var tmpBitmap = Image.FromHbitmap(safeDibSectionHandle.DangerousGetHandle());
// Create a new bitmap which has a transparent background
var returnBitmap = new UnmanagedBitmap<Bgra32>(tmpBitmap.Width, tmpBitmap.Height, tmpBitmap.HorizontalResolution, tmpBitmap.VerticalResolution);
returnBitmap.Span.Fill(Color.Transparent.FromColorWithAlpha());
// Content will be copied here
using (var graphics = Graphics.FromImage(returnBitmap.NativeBitmap))
{
// For all screens copy the content to the new bitmap
foreach (var screen in Screen.AllScreens)
{
if (screen.Bounds.IntersectsWith(captureBounds))
{
screensInsideCapture.Add(screen);
}
// Make sure the bounds are with an offset to the capture bounds
var screenBounds = screen.Bounds;
screenBounds.Offset(-captureBounds.X, -captureBounds.Y);
graphics.DrawImage(tmpBitmap, screenBounds, screenBounds.X, screenBounds.Y, screenBounds.Width, screenBounds.Height, GraphicsUnit.Pixel);
}
// Check all all screens are of an equal size
bool offscreenContent;
using (var captureRegion = new Region(captureBounds))
{
// Exclude every visible part
foreach (var screen in screensInsideCapture)
{
captureRegion.Exclude(screen.Bounds);
}
// If the region is not empty, we have "offscreenContent"
using (var screenGraphics = Graphics.FromHwnd(User32Api.GetDesktopWindow()))
{
offscreenContent = !captureRegion.IsEmpty(screenGraphics);
}
}
// Check if we need to have a transparent background, needed for offscreen content
if (offscreenContent)
{
using (var tmpBitmap = Image.FromHbitmap(safeDibSectionHandle.DangerousGetHandle()))
{
// Create a new bitmap which has a transparent background
var returnBitmap = new UnmanagedBitmap<Bgra32>(tmpBitmap.Width, tmpBitmap.Height, tmpBitmap.HorizontalResolution, tmpBitmap.VerticalResolution);
returnBitmap.Span.Fill(Color.Transparent.FromColorWithAlpha());
// Content will be copied here
using (var graphics = Graphics.FromImage(returnBitmap.NativeBitmap))
{
// For all screens copy the content to the new bitmap
foreach (var screen in Screen.AllScreens)
{
// Make sure the bounds are with an offset to the capture bounds
var screenBounds = screen.Bounds;
screenBounds.Offset(-captureBounds.X, -captureBounds.Y);
graphics.DrawImage(tmpBitmap, screenBounds, screenBounds.X, screenBounds.Y, screenBounds.Width, screenBounds.Height, GraphicsUnit.Pixel);
}
}
}
return returnBitmap;
}
}
else
{
// All screens, which are inside the capture, are of equal size
// assign image to Capture, the image will be disposed there..
// TODO: Optimize?
return BitmapWrapper.FromBitmap(Image.FromHbitmap(safeDibSectionHandle.DangerousGetHandle()));
}
}
catch (ExternalException ee)
{
Log.Warn().WriteLine(ee, "Problem getting bitmap at try " + i + " : ");
exception = ee;
}
return returnBitmap;
}
Log.Error().WriteLine(null, "Still couldn't create Bitmap!");
if (exception != null)
else
{
throw exception;
// All screens, which are inside the capture, are of equal size
// assign image to Capture, the image will be disposed there..
// TODO: Optimize?
return BitmapWrapper.FromBitmap(Image.FromHbitmap(safeDibSectionHandle.DangerousGetHandle()));
}
}
catch (ExternalException ee)
{
Log.Warn().WriteLine(ee, "Problem getting bitmap at try " + i + " : ");
exception = ee;
}
}
Log.Error().WriteLine(null, "Still couldn't create Bitmap!");
if (exception != null)
{
throw exception;
}
}

View file

@ -178,14 +178,12 @@ namespace Greenshot.Addons.Extensions
/// <param name="outputSettings">SurfaceOutputSettings specifying how to output the surface</param>
public static void SetAsBitmap(this IClipboardAccessToken clipboardAccessToken, ISurface surface, SurfaceOutputSettings outputSettings)
{
using (var bitmapStream = new MemoryStream())
{
ImageOutput.SaveToStream(surface, bitmapStream, outputSettings);
bitmapStream.Seek(0, SeekOrigin.Begin);
// Set the stream
var clipboardFormat = ClipboardFormatExtensions.MapFormatToId(outputSettings.Format.ToString().ToUpperInvariant());
clipboardAccessToken.SetAsStream(clipboardFormat, bitmapStream);
}
using var bitmapStream = new MemoryStream();
ImageOutput.SaveToStream(surface, bitmapStream, outputSettings);
bitmapStream.Seek(0, SeekOrigin.Begin);
// Set the stream
var clipboardFormat = ClipboardFormatExtensions.MapFormatToId(outputSettings.Format.ToString().ToUpperInvariant());
clipboardAccessToken.SetAsStream(clipboardFormat, bitmapStream);
}
/// <summary>
@ -196,39 +194,37 @@ namespace Greenshot.Addons.Extensions
public static void SetAsFormat17(this IClipboardAccessToken clipboardAccessToken, ISurface surface, ICoreConfiguration coreConfiguration)
{
// Create the stream for the clipboard
using (var dibV5Stream = new MemoryStream())
using var dibV5Stream = new MemoryStream();
var outputSettings = new SurfaceOutputSettings(coreConfiguration, OutputFormats.bmp, 100, false);
bool dispose = ImageOutput.CreateBitmapFromSurface(surface, outputSettings, out var bitmapToSave);
// Create the BITMAPINFOHEADER
var header = BitmapInfoHeader.Create(bitmapToSave.Width, bitmapToSave.Height, 32);
// Make sure we have BI_BITFIELDS, this seems to be normal for Format17?
header.Compression = BitmapCompressionMethods.BI_BITFIELDS;
var headerBytes = BinaryStructHelper.ToByteArray(header);
// Write the BITMAPINFOHEADER to the stream
dibV5Stream.Write(headerBytes, 0, headerBytes.Length);
// As we have specified BI_COMPRESSION.BI_BITFIELDS, the BitfieldColorMask needs to be added
var colorMask = BitfieldColorMask.Create();
// Create the byte[] from the struct
var colorMaskBytes = BinaryStructHelper.ToByteArray(colorMask);
Array.Reverse(colorMaskBytes);
// Write to the stream
dibV5Stream.Write(colorMaskBytes, 0, colorMaskBytes.Length);
// Create the raw bytes for the pixels only
var bitmapBytes = BitmapToByteArray(bitmapToSave);
// Write to the stream
dibV5Stream.Write(bitmapBytes, 0, bitmapBytes.Length);
// Reset the stream to the beginning so it can be written
dibV5Stream.Seek(0, SeekOrigin.Begin);
// Set the DIBv5 to the clipboard DataObject
clipboardAccessToken.SetAsStream("Format17", dibV5Stream);
if (dispose)
{
var outputSettings = new SurfaceOutputSettings(coreConfiguration, OutputFormats.bmp, 100, false);
bool dispose = ImageOutput.CreateBitmapFromSurface(surface, outputSettings, out var bitmapToSave);
// Create the BITMAPINFOHEADER
var header = BitmapInfoHeader.Create(bitmapToSave.Width, bitmapToSave.Height, 32);
// Make sure we have BI_BITFIELDS, this seems to be normal for Format17?
header.Compression = BitmapCompressionMethods.BI_BITFIELDS;
var headerBytes = BinaryStructHelper.ToByteArray(header);
// Write the BITMAPINFOHEADER to the stream
dibV5Stream.Write(headerBytes, 0, headerBytes.Length);
// As we have specified BI_COMPRESSION.BI_BITFIELDS, the BitfieldColorMask needs to be added
var colorMask = BitfieldColorMask.Create();
// Create the byte[] from the struct
var colorMaskBytes = BinaryStructHelper.ToByteArray(colorMask);
Array.Reverse(colorMaskBytes);
// Write to the stream
dibV5Stream.Write(colorMaskBytes, 0, colorMaskBytes.Length);
// Create the raw bytes for the pixels only
var bitmapBytes = BitmapToByteArray(bitmapToSave);
// Write to the stream
dibV5Stream.Write(bitmapBytes, 0, bitmapBytes.Length);
// Reset the stream to the beginning so it can be written
dibV5Stream.Seek(0, SeekOrigin.Begin);
// Set the DIBv5 to the clipboard DataObject
clipboardAccessToken.SetAsStream("Format17", dibV5Stream);
if (dispose)
{
bitmapToSave.Dispose();
}
bitmapToSave.Dispose();
}
}
@ -269,13 +265,11 @@ namespace Greenshot.Addons.Extensions
/// <param name="surface">ISurface</param>
public static void SetAsDeviceIndependendBitmap(this IClipboardAccessToken clipboardAccessToken, ISurface surface, ICoreConfiguration coreConfiguration)
{
using (var bitmapStream = new MemoryStream())
{
ImageOutput.SaveToStream(surface, bitmapStream, new SurfaceOutputSettings(coreConfiguration) {Format = OutputFormats.bmp});
bitmapStream.Seek(Marshal.SizeOf(typeof(BitmapFileHeader)), SeekOrigin.Begin);
// Set the stream
clipboardAccessToken.SetAsStream(StandardClipboardFormats.DeviceIndependentBitmap, bitmapStream);
}
using var bitmapStream = new MemoryStream();
ImageOutput.SaveToStream(surface, bitmapStream, new SurfaceOutputSettings(coreConfiguration) {Format = OutputFormats.bmp});
bitmapStream.Seek(Marshal.SizeOf(typeof(BitmapFileHeader)), SeekOrigin.Begin);
// Set the stream
clipboardAccessToken.SetAsStream(StandardClipboardFormats.DeviceIndependentBitmap, bitmapStream);
}
}
}

View file

@ -155,15 +155,13 @@ EndSelection:<<<<<<<4
/// <param name="coreConfiguration">ICoreConfiguration</param>
public static void SetAsEmbeddedHtml(this IClipboardAccessToken clipboardAccessToken, ISurface surface, ICoreConfiguration coreConfiguration)
{
using (var pngStream = new MemoryStream())
{
var pngOutputSettings = new SurfaceOutputSettings(coreConfiguration, OutputFormats.png, 100, false);
ImageOutput.SaveToStream(surface, pngStream, pngOutputSettings);
pngStream.Seek(0, SeekOrigin.Begin);
// Set the PNG stream
var htmlText = GenerateHtmlDataUrlString(new NativeSize(surface.Width, surface.Height), pngStream);
clipboardAccessToken.SetAsHtml(htmlText);
}
using var pngStream = new MemoryStream();
var pngOutputSettings = new SurfaceOutputSettings(coreConfiguration, OutputFormats.png, 100, false);
ImageOutput.SaveToStream(surface, pngStream, pngOutputSettings);
pngStream.Seek(0, SeekOrigin.Begin);
// Set the PNG stream
var htmlText = GenerateHtmlDataUrlString(new NativeSize(surface.Width, surface.Height), pngStream);
clipboardAccessToken.SetAsHtml(htmlText);
}
/// <summary>

View file

@ -16,10 +16,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Dapplo.CaliburnMicro.Configuration" Version="2.1.3" />
<PackageReference Include="Dapplo.CaliburnMicro.Metro" Version="2.1.3" />
<PackageReference Include="Dapplo.CaliburnMicro.Toasts" Version="2.1.3" />
<PackageReference Include="Dapplo.CaliburnMicro.Translations" Version="2.1.3" />
<PackageReference Include="Dapplo.CaliburnMicro.Configuration" Version="2.1.4" />
<PackageReference Include="Dapplo.CaliburnMicro.Metro" Version="2.1.4" />
<PackageReference Include="Dapplo.CaliburnMicro.Toasts" Version="2.1.4" />
<PackageReference Include="Dapplo.CaliburnMicro.Translations" Version="2.1.4" />
<PackageReference Include="Dapplo.HttpExtensions" Version="0.10.7" />
<PackageReference Include="Dapplo.HttpExtensions.JsonNet" Version="0.10.7" />
<PackageReference Include="Dapplo.HttpExtensions.OAuth" Version="0.10.7" />
@ -27,9 +27,9 @@
<PackageReference Include="Dapplo.Windows.Clipboard" Version="0.11.6" />
<PackageReference Include="Dapplo.Windows.Dpi" Version="0.11.6" />
<PackageReference Include="Dapplo.Windows.Icons" Version="0.11.6" />
<PackageReference Include="gong-wpf-dragdrop" Version="2.1.0" />
<PackageReference Include="MahApps.Metro.IconPacks" Version="3.0.0-alpha0223" />
<PackageReference Include="Svg" Version="3.0.49" />
<PackageReference Include="gong-wpf-dragdrop" Version="2.2.0" />
<PackageReference Include="MahApps.Metro.IconPacks" Version="3.0.0" />
<PackageReference Include="Svg" Version="3.0.84" />
</ItemGroup>
<ItemGroup>

View file

@ -47,11 +47,9 @@ namespace Greenshot.Addons.Resources
/// </summary>
/// <returns>BitmapSource</returns>
public BitmapSource GreenshotIconAsBitmapSource()
{
using (var icon = GetGreenshotIcon())
{
return icon.ToBitmapSource();
}
{
using var icon = GetGreenshotIcon();
return icon.ToBitmapSource();
}
/// <summary>
@ -70,12 +68,10 @@ namespace Greenshot.Addons.Resources
/// <param name="type">Type</param>
/// <returns>Icon</returns>
public Icon GetIcon(string name, Type type = null)
{
using (var iconStream = _resourceProvider.ResourceAsStream((type ?? GetType()).Assembly, "Resources", $"{name}.Icon.ico"))
{
return new Icon(iconStream);
}
}
{
using var iconStream = _resourceProvider.ResourceAsStream((type ?? GetType()).Assembly, "Resources", $"{name}.Icon.ico");
return new Icon(iconStream);
}
/// <summary>
/// Get the Greenshot logo as a Bitmap
@ -99,11 +95,10 @@ namespace Greenshot.Addons.Resources
name += ".png";
}
using (var imageStream = _resourceProvider.ResourceAsStream((type ?? GetType()).Assembly, "Resources", name))
{
return BitmapHelper.FromStream(imageStream);
}
}
using var imageStream = _resourceProvider.ResourceAsStream((type ?? GetType()).Assembly, "Resources", name);
return BitmapHelper.FromStream(imageStream);
}
/// <summary>
/// Get a byte[] from an embedded resource
@ -113,12 +108,10 @@ namespace Greenshot.Addons.Resources
/// <returns>bate[]</returns>
public byte[] GetBytes(string name, Type type = null)
{
using (var stream = _resourceProvider.ResourceAsStream((type ?? GetType()).Assembly, "Resources", name))
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
using var stream = _resourceProvider.ResourceAsStream((type ?? GetType()).Assembly, "Resources", name);
using var memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
}

View file

@ -63,10 +63,8 @@ namespace Greenshot.Addons.ViewModels
Information = exportInformation;
Source = source;
using (var bitmap = exportedSurface.GetBitmapForExport())
{
ExportBitmapSource = bitmap.NativeBitmap.ToBitmapSource();
}
using var bitmap = exportedSurface.GetBitmapForExport();
ExportBitmapSource = bitmap.NativeBitmap.ToBitmapSource();
}
/// <summary>

View file

@ -112,17 +112,17 @@ namespace Greenshot.Addons.ViewModels
/// </summary>
public void SelectOutputPath()
{
using (var folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog())
using var folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog
{
// Get the storage location and replace the environment variables
folderBrowserDialog.SelectedPath = FilenameHelper.FillVariables(CoreConfiguration.OutputFilePath, false);
if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
SelectedPath = FilenameHelper.FillVariables(CoreConfiguration.OutputFilePath, false)
};
// Get the storage location and replace the environment variables
if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
// Only change if there is a change, otherwise we might overwrite the environment variables
if (folderBrowserDialog.SelectedPath != null && !folderBrowserDialog.SelectedPath.Equals(FilenameHelper.FillVariables(CoreConfiguration.OutputFilePath, false)))
{
// Only change if there is a change, otherwise we might overwrite the environment variables
if (folderBrowserDialog.SelectedPath != null && !folderBrowserDialog.SelectedPath.Equals(FilenameHelper.FillVariables(CoreConfiguration.OutputFilePath, false)))
{
CoreConfiguration.OutputFilePath = folderBrowserDialog.SelectedPath;
}
CoreConfiguration.OutputFilePath = folderBrowserDialog.SelectedPath;
}
}
}

View file

@ -166,36 +166,34 @@ namespace Greenshot.Core.Extensions
{
// Assume using it's own location
formLocation = windowRectangle.Location;
using (var workingArea = new Region())
using var workingArea = new Region();
// Find the screen where the window is and check if it fits
foreach (var displayInfo in DisplayInfo.AllDisplayInfos)
{
// Find the screen where the window is and check if it fits
workingArea.Union(displayInfo.WorkingArea);
}
// If the formLocation is not inside the visible area
if (!workingArea.AreRectangleCornersVisisble(windowRectangle))
{
// If none found we find the biggest screen
foreach (var displayInfo in DisplayInfo.AllDisplayInfos)
{
workingArea.Union(displayInfo.WorkingArea);
}
// If the formLocation is not inside the visible area
if (!workingArea.AreRectangleCornersVisisble(windowRectangle))
{
// If none found we find the biggest screen
foreach (var displayInfo in DisplayInfo.AllDisplayInfos)
var newWindowRectangle = new NativeRect(displayInfo.WorkingArea.Location, windowRectangle.Size);
if (!workingArea.AreRectangleCornersVisisble(newWindowRectangle))
{
var newWindowRectangle = new NativeRect(displayInfo.WorkingArea.Location, windowRectangle.Size);
if (!workingArea.AreRectangleCornersVisisble(newWindowRectangle))
{
continue;
}
formLocation = displayInfo.Bounds.Location;
doesCaptureFit = true;
break;
continue;
}
}
else
{
formLocation = displayInfo.Bounds.Location;
doesCaptureFit = true;
break;
}
}
else
{
doesCaptureFit = true;
}
}
else if (!WindowsVersion.IsWindows8OrLater)
{
@ -229,13 +227,11 @@ namespace Greenshot.Core.Extensions
if (!doesCaptureFit)
{
// if GDI is allowed.. (a screenshot won't be better than we comes if we continue)
using (var thisWindowProcess = Process.GetProcessById(interopWindow.GetProcessId()))
using var thisWindowProcess = Process.GetProcessById(interopWindow.GetProcessId());
if (!interopWindow.IsApp() && IsGdiAllowed(thisWindowProcess, captureConfiguration))
{
if (!interopWindow.IsApp() && IsGdiAllowed(thisWindowProcess, captureConfiguration))
{
// we return null which causes the capturing code to try another method.
return null;
}
// we return null which causes the capturing code to try another method.
return null;
}
}
}

View file

@ -95,85 +95,79 @@ namespace Greenshot.Core.Sources
}
// create a device context we can copy to
using (var safeCompatibleDcHandle = Gdi32Api.CreateCompatibleDC(desktopDcHandle))
using var safeCompatibleDcHandle = Gdi32Api.CreateCompatibleDC(desktopDcHandle);
// Check if the device context is there, if not throw an error with as much info as possible!
if (safeCompatibleDcHandle.IsInvalid)
{
// Check if the device context is there, if not throw an error with as much info as possible!
if (safeCompatibleDcHandle.IsInvalid)
// Get Exception before the error is lost
var exceptionToThrow = CreateCaptureException("CreateCompatibleDC", captureBounds);
// throw exception
throw exceptionToThrow;
}
// Create BITMAPINFOHEADER for CreateDIBSection
var bmi = BitmapInfoHeader.Create(captureBounds.Width, captureBounds.Height, 24);
// Make sure the last error is set to 0
Win32.SetLastError(0);
// create a bitmap we can copy it to, using GetDeviceCaps to get the width/height
using var safeDibSectionHandle = Gdi32Api.CreateDIBSection(desktopDcHandle, ref bmi, 0, out var _, IntPtr.Zero, 0);
if (safeDibSectionHandle.IsInvalid)
{
// Get Exception before the error is lost
var exceptionToThrow = CreateCaptureException("CreateDIBSection", captureBounds);
exceptionToThrow.Data.Add("hdcDest", safeCompatibleDcHandle.DangerousGetHandle().ToInt32());
exceptionToThrow.Data.Add("hdcSrc", desktopDcHandle.DangerousGetHandle().ToInt32());
// Throw so people can report the problem
throw exceptionToThrow;
}
// select the bitmap object and store the old handle
using (safeCompatibleDcHandle.SelectObject(safeDibSectionHandle))
{
// bitblt over (make copy)
// ReSharper disable once BitwiseOperatorOnEnumWithoutFlags
Gdi32Api.BitBlt(safeCompatibleDcHandle, 0, 0, captureBounds.Width, captureBounds.Height, desktopDcHandle, captureBounds.X, captureBounds.Y,
RasterOperations.SourceCopy | RasterOperations.CaptureBlt);
}
// Create BitmapSource from the DibSection
capturedBitmapSource = Imaging.CreateBitmapSourceFromHBitmap(safeDibSectionHandle.DangerousGetHandle(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
// Now cut away invisible parts
// Collect all screens inside this capture
var displaysInsideCapture = new List<DisplayInfo>();
foreach (var displayInfo in DisplayInfo.AllDisplayInfos)
{
if (displayInfo.Bounds.IntersectsWith(captureBounds))
{
// Get Exception before the error is lost
var exceptionToThrow = CreateCaptureException("CreateCompatibleDC", captureBounds);
// throw exception
throw exceptionToThrow;
displaysInsideCapture.Add(displayInfo);
}
// Create BITMAPINFOHEADER for CreateDIBSection
var bmi = BitmapInfoHeader.Create(captureBounds.Width, captureBounds.Height, 24);
// Make sure the last error is set to 0
Win32.SetLastError(0);
// create a bitmap we can copy it to, using GetDeviceCaps to get the width/height
using (var safeDibSectionHandle = Gdi32Api.CreateDIBSection(desktopDcHandle, ref bmi, 0, out var _, IntPtr.Zero, 0))
}
// Check all all screens are of an equal size
bool offscreenContent;
using (var captureRegion = new Region(captureBounds))
{
// Exclude every visible part
foreach (var displayInfo in displaysInsideCapture)
{
if (safeDibSectionHandle.IsInvalid)
{
// Get Exception before the error is lost
var exceptionToThrow = CreateCaptureException("CreateDIBSection", captureBounds);
exceptionToThrow.Data.Add("hdcDest", safeCompatibleDcHandle.DangerousGetHandle().ToInt32());
exceptionToThrow.Data.Add("hdcSrc", desktopDcHandle.DangerousGetHandle().ToInt32());
// Throw so people can report the problem
throw exceptionToThrow;
}
// select the bitmap object and store the old handle
using (safeCompatibleDcHandle.SelectObject(safeDibSectionHandle))
{
// bitblt over (make copy)
// ReSharper disable once BitwiseOperatorOnEnumWithoutFlags
Gdi32Api.BitBlt(safeCompatibleDcHandle, 0, 0, captureBounds.Width, captureBounds.Height, desktopDcHandle, captureBounds.X, captureBounds.Y,
RasterOperations.SourceCopy | RasterOperations.CaptureBlt);
}
// Create BitmapSource from the DibSection
capturedBitmapSource = Imaging.CreateBitmapSourceFromHBitmap(safeDibSectionHandle.DangerousGetHandle(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
// Now cut away invisible parts
// Collect all screens inside this capture
var displaysInsideCapture = new List<DisplayInfo>();
foreach (var displayInfo in DisplayInfo.AllDisplayInfos)
{
if (displayInfo.Bounds.IntersectsWith(captureBounds))
{
displaysInsideCapture.Add(displayInfo);
}
}
// Check all all screens are of an equal size
bool offscreenContent;
using (var captureRegion = new Region(captureBounds))
{
// Exclude every visible part
foreach (var displayInfo in displaysInsideCapture)
{
captureRegion.Exclude(displayInfo.Bounds);
}
// If the region is not empty, we have "offscreenContent"
using (var screenGraphics = Graphics.FromHwnd(User32Api.GetDesktopWindow()))
{
offscreenContent = !captureRegion.IsEmpty(screenGraphics);
}
}
// Check if we need to have a transparent background, needed for offscreen content
if (offscreenContent)
{
var modifiedImage = new WriteableBitmap(capturedBitmapSource.PixelWidth, capturedBitmapSource.PixelHeight, capturedBitmapSource.DpiX, capturedBitmapSource.DpiY, PixelFormats.Bgr32, capturedBitmapSource.Palette);
foreach (var displayInfo in DisplayInfo.AllDisplayInfos)
{
modifiedImage.CopyPixels(capturedBitmapSource, displayInfo.Bounds);
}
capturedBitmapSource = modifiedImage;
}
captureRegion.Exclude(displayInfo.Bounds);
}
// If the region is not empty, we have "offscreenContent"
using var screenGraphics = Graphics.FromHwnd(User32Api.GetDesktopWindow());
offscreenContent = !captureRegion.IsEmpty(screenGraphics);
}
// Check if we need to have a transparent background, needed for offscreen content
if (offscreenContent)
{
var modifiedImage = new WriteableBitmap(capturedBitmapSource.PixelWidth, capturedBitmapSource.PixelHeight, capturedBitmapSource.DpiX, capturedBitmapSource.DpiY, PixelFormats.Bgr32, capturedBitmapSource.Palette);
foreach (var displayInfo in DisplayInfo.AllDisplayInfos)
{
modifiedImage.CopyPixels(capturedBitmapSource, displayInfo.Bounds);
}
capturedBitmapSource = modifiedImage;
}
}
var result = new CaptureElement<BitmapSource>(captureBounds.Location, capturedBitmapSource)

View file

@ -171,22 +171,20 @@ namespace Greenshot.Gfx
// Make sure both images have the same resolution
newImage.SetResolution(sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution);
using (var graphics = Graphics.FromImage(newImage))
using var graphics = Graphics.FromImage(newImage);
if (fromTransparentToNon)
{
if (fromTransparentToNon)
{
// Rule 2: Make sure the background color is white
graphics.Clear(Color.White);
}
// decide fastest copy method
if (isAreaEqual)
{
graphics.DrawImageUnscaled(sourceBitmap.NativeBitmap, 0, 0);
}
else
{
graphics.DrawImage(sourceBitmap.NativeBitmap, 0, 0, sourceRect, GraphicsUnit.Pixel);
}
// Rule 2: Make sure the background color is white
graphics.Clear(Color.White);
}
// decide fastest copy method
if (isAreaEqual)
{
graphics.DrawImageUnscaled(sourceBitmap.NativeBitmap, 0, 0);
}
else
{
graphics.DrawImage(sourceBitmap.NativeBitmap, 0, 0, sourceRect, GraphicsUnit.Pixel);
}
}
else

View file

@ -462,13 +462,11 @@ namespace Greenshot.Gfx
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
// draw original with a TextureBrush so we have nice anti-aliasing!
using (Brush textureBrush = new TextureBrush(sourceBitmap.NativeBitmap, WrapMode.Clamp))
{
// We need to do a translate-transform otherwise the image is wrapped
graphics.TranslateTransform(offset.X, offset.Y);
graphics.FillRectangle(textureBrush, 0, 0, sourceBitmap.Width, sourceBitmap.Height);
}
}
using Brush textureBrush = new TextureBrush(sourceBitmap.NativeBitmap, WrapMode.Clamp);
// We need to do a translate-transform otherwise the image is wrapped
graphics.TranslateTransform(offset.X, offset.Y);
graphics.FillRectangle(textureBrush, 0, 0, sourceBitmap.Width, sourceBitmap.Height);
}
return returnImage;
}
@ -491,14 +489,12 @@ namespace Greenshot.Gfx
/// <param name="dest">Image to copy to</param>
/// <param name="colorMatrix">ColorMatrix to apply</param>
public static void ApplyColorMatrix(this IBitmapWithNativeSupport source, NativeRect sourceRect, IBitmapWithNativeSupport dest, NativeRect destRect, ColorMatrix colorMatrix)
{
using (var imageAttributes = new ImageAttributes())
{
imageAttributes.ClearColorMatrix();
imageAttributes.SetColorMatrix(colorMatrix);
source.ApplyImageAttributes(sourceRect, dest, destRect, imageAttributes);
}
}
{
using var imageAttributes = new ImageAttributes();
imageAttributes.ClearColorMatrix();
imageAttributes.SetColorMatrix(colorMatrix);
source.ApplyImageAttributes(sourceRect, dest, destRect, imageAttributes);
}
/// <summary>
/// Apply image attributes to the image
@ -532,18 +528,17 @@ namespace Greenshot.Gfx
{
destRect = new NativeRect(0, 0, dest.Width, dest.Height);
}
using (var graphics = Graphics.FromImage(dest.NativeBitmap))
{
// Make sure we draw with the best quality!
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.DrawImage(source.NativeBitmap, destRect, sourceRect.X, sourceRect.Y, sourceRect.Width, sourceRect.Height, GraphicsUnit.Pixel, imageAttributes);
}
}
using var graphics = Graphics.FromImage(dest.NativeBitmap);
// Make sure we draw with the best quality!
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.DrawImage(source.NativeBitmap, destRect, sourceRect.X, sourceRect.Y, sourceRect.Width, sourceRect.Height, GraphicsUnit.Pixel, imageAttributes);
}
/// <summary>
/// Checks if the supplied Bitmap has a PixelFormat we support
@ -712,12 +707,10 @@ namespace Greenshot.Gfx
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = interpolationMode;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(sourceImage.NativeBitmap, new NativeRect(destX, destY, destWidth, destHeight), 0, 0, sourceImage.Width, sourceImage.Height, GraphicsUnit.Pixel, wrapMode);
}
}
using var wrapMode = new ImageAttributes();
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(sourceImage.NativeBitmap, new NativeRect(destX, destY, destWidth, destHeight), 0, 0, sourceImage.Width, sourceImage.Height, GraphicsUnit.Pixel, wrapMode);
}
return newBitmap;
}
@ -737,35 +730,34 @@ namespace Greenshot.Gfx
{
toCount = toCount & 0xffffff;
}
using (var bb = FastBitmapFactory.Create(sourceImage))
{
Parallel.For(0, bb.Height, () => 0, (y, state, initialColorCount) =>
{
var currentColors = initialColorCount;
for (var x = 0; x < bb.Width; x++)
{
var bitmapcolor = bb.GetColorAt(x, y).ToArgb();
if (!includeAlpha)
{
bitmapcolor = bitmapcolor & 0xffffff;
}
if (bitmapcolor == toCount)
{
currentColors++;
}
}
return currentColors;
}, lineColorCount =>
{
lock (lockObject)
{
colors += lineColorCount;
}
});
return colors;
}
}
using var bb = FastBitmapFactory.Create(sourceImage);
Parallel.For(0, bb.Height, () => 0, (y, state, initialColorCount) =>
{
var currentColors = initialColorCount;
for (var x = 0; x < bb.Width; x++)
{
var bitmapcolor = bb.GetColorAt(x, y).ToArgb();
if (!includeAlpha)
{
bitmapcolor = bitmapcolor & 0xffffff;
}
if (bitmapcolor == toCount)
{
currentColors++;
}
}
return currentColors;
}, lineColorCount =>
{
lock (lockObject)
{
colors += lineColorCount;
}
});
return colors;
}
/// <summary>
/// Create an image from a stream, if an extension is supplied more formats are supported.
@ -833,12 +825,10 @@ namespace Greenshot.Gfx
return original.Scale3X();
}
if (width == original.Width * 4)
{
using (var scale2X = original.Scale2X())
{
return scale2X.Scale2X();
}
}
{
using var scale2X = original.Scale2X();
return scale2X.Scale2X();
}
return original.Resize(true, width, width, interpolationMode: InterpolationMode.NearestNeighbor);
}
@ -865,30 +855,31 @@ namespace Greenshot.Gfx
}
bool result = true;
using (var fastBitmap1 = FastBitmapFactory.Create(bitmap1))
using (var fastBitmap2 = FastBitmapFactory.Create(bitmap2))
{
Parallel.For(0, fastBitmap1.Height, (y, state) =>
{
unsafe
{
var tmpColor1 = stackalloc byte[4];
var tmpColor2 = stackalloc byte[4];
for (int x = 0; x < fastBitmap1.Width; x++)
{
fastBitmap1.GetColorAt(x, y, tmpColor1);
fastBitmap2.GetColorAt(x, y, tmpColor2);
if (AreColorsSame(tmpColor1, tmpColor2, fastBitmap1.HasAlphaChannel))
{
continue;
}
Log.Debug().WriteLine("Different colors at {0},{1}", x, y);
{
using var fastBitmap2 = FastBitmapFactory.Create(bitmap2);
Parallel.For(0, fastBitmap1.Height, (y, state) =>
{
unsafe
{
var tmpColor1 = stackalloc byte[4];
var tmpColor2 = stackalloc byte[4];
for (int x = 0; x < fastBitmap1.Width; x++)
{
fastBitmap1.GetColorAt(x, y, tmpColor1);
fastBitmap2.GetColorAt(x, y, tmpColor2);
if (AreColorsSame(tmpColor1, tmpColor2, fastBitmap1.HasAlphaChannel))
{
continue;
}
Log.Debug().WriteLine("Different colors at {0},{1}", x, y);
result = false;
state.Break();
}
}
});
}
return result;
state.Break();
}
}
});
}
return result;
}
/// <summary>

View file

@ -36,10 +36,8 @@ namespace Greenshot.Gfx
public static void ApplyBoxBlur(this IBitmapWithNativeSupport destinationBitmap, int range)
{
// We only need one fastbitmap as we use it as source and target (the reading is done for one line H/V, writing after "parsing" one line H/V)
using (var fastBitmap = FastBitmapFactory.Create(destinationBitmap))
{
fastBitmap.ApplyBoxBlur(range);
}
using var fastBitmap = FastBitmapFactory.Create(destinationBitmap);
fastBitmap.ApplyBoxBlur(range);
}
/// <summary>

View file

@ -76,22 +76,19 @@ namespace Greenshot.Gfx.Effects
using (var path = new GraphicsPath())
{
path.AddRectangle(new NativeRect(borderSize >> 1, borderSize >> 1, newImage.Width - borderSize, newImage.Height - borderSize));
using (var pen = new Pen(borderColor, borderSize))
{
pen.LineJoin = LineJoin.Round;
pen.StartCap = LineCap.Round;
pen.EndCap = LineCap.Round;
graphics.DrawPath(pen, path);
}
}
using var pen = new Pen(borderColor, borderSize) {
LineJoin = LineJoin.Round,
StartCap = LineCap.Round,
EndCap = LineCap.Round
};
graphics.DrawPath(pen, path);
}
// draw original with a TextureBrush so we have nice anti-aliasing!
using (Brush textureBrush = new TextureBrush(sourceBitmap.NativeBitmap, WrapMode.Clamp))
{
// We need to do a translate-tranform otherwise the image is wrapped
graphics.TranslateTransform(offset.X, offset.Y);
graphics.FillRectangle(textureBrush, 0, 0, sourceBitmap.Width, sourceBitmap.Height);
}
}
using Brush textureBrush = new TextureBrush(sourceBitmap.NativeBitmap, WrapMode.Clamp);
// We need to do a translate-tranform otherwise the image is wrapped
graphics.TranslateTransform(offset.X, offset.Y);
graphics.FillRectangle(textureBrush, 0, 0, sourceBitmap.Width, sourceBitmap.Height);
}
return newImage;
}

View file

@ -50,23 +50,21 @@ namespace Greenshot.Gfx.Effects
/// <param name="threshold">Threshold for monochrome filter (0 - 255), lower value means less black</param>
/// <returns>b/w bitmap</returns>
public static IBitmapWithNativeSupport CreateMonochrome(IBitmapWithNativeSupport sourceBitmap, byte threshold)
{
using (var fastBitmap = FastBitmapFactory.CreateCloneOf(sourceBitmap, sourceBitmap.PixelFormat))
{
Parallel.For(0, fastBitmap.Height, y =>
{
// TODO: use stackalloc / unsafe
for (var x = 0; x < fastBitmap.Width; x++)
{
var color = fastBitmap.GetColorAt(x, y);
var colorBrightness = (color.R + color.G + color.B) / 3 > threshold ? 255 : 0;
var monoColor = Color.FromArgb(color.A, colorBrightness, colorBrightness, colorBrightness);
fastBitmap.SetColorAt(x, y, ref monoColor);
}
});
return fastBitmap.UnlockAndReturnBitmap();
}
}
{
using var fastBitmap = FastBitmapFactory.CreateCloneOf(sourceBitmap, sourceBitmap.PixelFormat);
Parallel.For(0, fastBitmap.Height, y =>
{
// TODO: use stackalloc / unsafe
for (var x = 0; x < fastBitmap.Width; x++)
{
var color = fastBitmap.GetColorAt(x, y);
var colorBrightness = (color.R + color.G + color.B) / 3 > threshold ? 255 : 0;
var monoColor = Color.FromArgb(color.A, colorBrightness, colorBrightness, colorBrightness);
fastBitmap.SetColorAt(x, y, ref monoColor);
}
});
return fastBitmap.UnlockAndReturnBitmap();
}
}

View file

@ -193,19 +193,15 @@ namespace Greenshot.Gfx.Effects
path.CloseFigure();
// Draw the created figure with the original image by using a TextureBrush so we have anti-aliasing
using (var graphics = Graphics.FromImage(returnBitmap.NativeBitmap))
{
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
using (Brush brush = new TextureBrush(sourceBitmap.NativeBitmap))
{
// Important note: If the target wouldn't be at 0,0 we need to translate-transform!!
graphics.FillPath(brush, path);
}
}
}
using var graphics = Graphics.FromImage(returnBitmap.NativeBitmap);
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
using Brush brush = new TextureBrush(sourceBitmap.NativeBitmap);
// Important note: If the target wouldn't be at 0,0 we need to translate-transform!!
graphics.FillPath(brush, path);
}
return returnBitmap;
}

View file

@ -34,35 +34,25 @@ namespace Greenshot.Gfx.Extensions
/// </summary>
/// <param name="bitmap">IBitmapWithNativeSupport</param>
/// <returns>IBitmapWithNativeSupport</returns>
public static IBitmapWithNativeSupport Scale2X(this IBitmapWithNativeSupport bitmap)
{
switch (bitmap)
public static IBitmapWithNativeSupport Scale2X(this IBitmapWithNativeSupport bitmap) =>
bitmap switch
{
case UnmanagedBitmap<Bgra32> unmanagedBitmap:
return unmanagedBitmap.Scale2X();
case UnmanagedBitmap<Bgr32> unmanagedBitmap:
return unmanagedBitmap.Scale2X();
}
return ScaleX.Scale2X(bitmap);
}
UnmanagedBitmap<Bgra32> unmanagedBitmap => unmanagedBitmap.Scale2X(),
UnmanagedBitmap<Bgr32> unmanagedBitmap => unmanagedBitmap.Scale2X(),
_ => ScaleX.Scale2X(bitmap)
};
/// <summary>
/// Scale3x
/// </summary>
/// <param name="bitmap">IBitmapWithNativeSupport</param>
/// <returns>IBitmapWithNativeSupport</returns>
public static IBitmapWithNativeSupport Scale3X(this IBitmapWithNativeSupport bitmap)
{
switch (bitmap)
public static IBitmapWithNativeSupport Scale3X(this IBitmapWithNativeSupport bitmap) =>
bitmap switch
{
case UnmanagedBitmap<Bgra32> unmanagedBitmap:
return unmanagedBitmap.Scale3X();
case UnmanagedBitmap<Bgr32> unmanagedBitmap:
return unmanagedBitmap.Scale3X();
}
return ScaleX.Scale3X(bitmap);
}
UnmanagedBitmap<Bgra32> unmanagedBitmap => unmanagedBitmap.Scale3X(),
UnmanagedBitmap<Bgr32> unmanagedBitmap => unmanagedBitmap.Scale3X(),
_ => ScaleX.Scale3X(bitmap)
};
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
@ -20,15 +19,13 @@ namespace Greenshot.Gfx.Formats
/// <inheritdoc/>
public IBitmapWithNativeSupport Read(Stream stream, string extension = null)
{
using (var tmpImage = Image.FromStream(stream, true, true))
using var tmpImage = Image.FromStream(stream, true, true);
if (!(tmpImage is Bitmap bitmap))
{
if (!(tmpImage is Bitmap bitmap))
{
return null;
}
Log.Debug().WriteLine("Loaded bitmap with Size {0}x{1} and PixelFormat {2}", bitmap.Width, bitmap.Height, bitmap.PixelFormat);
return bitmap.CloneBitmap(PixelFormat.Format32bppArgb);
return null;
}
Log.Debug().WriteLine("Loaded bitmap with Size {0}x{1} and PixelFormat {2}", bitmap.Width, bitmap.Height, bitmap.PixelFormat);
return bitmap.CloneBitmap(PixelFormat.Format32bppArgb);
}
}
}

View file

@ -28,12 +28,10 @@ namespace Greenshot.Gfx.Formats
// Icon logic, try to get the Vista icon, else the biggest possible
try
{
using (var tmpBitmap = ExtractVistaIcon(stream))
using var tmpBitmap = ExtractVistaIcon(stream);
if (tmpBitmap != null)
{
if (tmpBitmap != null)
{
return tmpBitmap.CloneBitmap(PixelFormat.Format32bppArgb);
}
return tmpBitmap.CloneBitmap(PixelFormat.Format32bppArgb);
}
}
catch (Exception vistaIconException)
@ -45,13 +43,9 @@ namespace Greenshot.Gfx.Formats
// No vista icon, try normal icon
stream.Position = 0;
// We create a copy of the bitmap, so everything else can be disposed
using (var tmpIcon = new Icon(stream, new Size(1024, 1024)))
{
using (var tmpImage = tmpIcon.ToBitmap())
{
return tmpImage.CloneBitmap(PixelFormat.Format32bppArgb);
}
}
using var tmpIcon = new Icon(stream, new Size(1024, 1024));
using var tmpImage = tmpIcon.ToBitmap();
return tmpImage.CloneBitmap(PixelFormat.Format32bppArgb);
}
catch (Exception iconException)
{
@ -89,12 +83,10 @@ namespace Greenshot.Gfx.Formats
}
var iImageSize = BitConverter.ToInt32(srcBuf, sizeIconDir + sizeIconDirEntry * iIndex + 8);
var iImageOffset = BitConverter.ToInt32(srcBuf, sizeIconDir + sizeIconDirEntry * iIndex + 12);
using (var destStream = new MemoryStream())
{
destStream.Write(srcBuf, iImageOffset, iImageSize);
destStream.Seek(0, SeekOrigin.Begin);
bmpPngExtracted = BitmapWrapper.FromBitmap(new Bitmap(destStream)); // This is PNG! :)
}
using var destStream = new MemoryStream();
destStream.Write(srcBuf, iImageOffset, iImageSize);
destStream.Seek(0, SeekOrigin.Begin);
bmpPngExtracted = BitmapWrapper.FromBitmap(new Bitmap(destStream)); // This is PNG! :)
break;
}
}

View file

@ -10,7 +10,7 @@
<PackageReference Include="Dapplo.Log" Version="1.3.26" />
<PackageReference Include="Dapplo.Windows" Version="0.11.6" />
<PackageReference Include="Dapplo.Windows.Dpi" Version="0.11.6" />
<PackageReference Include="Svg" Version="3.0.49" />
<PackageReference Include="Svg" Version="3.0.84" />
<PackageReference Include="System.Memory" Version="4.5.3" />
</ItemGroup>
</Project>

View file

@ -105,53 +105,49 @@ namespace Greenshot.Gfx.Quantizer
}
// Use a bitmap to store the initial match, which is just as good as an array and saves us 2x the storage
using (var sourceFastBitmap = FastBitmapFactory.Create(sourceBitmap))
{
sourceFastBitmap.Lock();
using (var destinationFastBitmap = FastBitmapFactory.CreateEmpty(sourceBitmap.Size, PixelFormat.Format8bppIndexed, Color.White) as FastChunkyBitmap)
{
for (var y = 0; y < sourceFastBitmap.Height; y++)
{
for (var x = 0; x < sourceFastBitmap.Width; x++)
{
Color color;
if (!(sourceFastBitmap is IFastBitmapWithBlend sourceFastBitmapWithBlend))
{
color = sourceFastBitmap.GetColorAt(x, y);
}
else
{
color = sourceFastBitmapWithBlend.GetBlendedColorAt(x, y);
}
// To count the colors
var index = color.ToArgb() & 0x00ffffff;
// Check if we already have this color
if (!bitArray.Get(index))
{
// If not, add 1 to the single colors
_colorCount++;
bitArray.Set(index, true);
}
using var sourceFastBitmap = FastBitmapFactory.Create(sourceBitmap);
sourceFastBitmap.Lock();
using var destinationFastBitmap = FastBitmapFactory.CreateEmpty(sourceBitmap.Size, PixelFormat.Format8bppIndexed, Color.White) as FastChunkyBitmap;
for (var y = 0; y < sourceFastBitmap.Height; y++)
{
for (var x = 0; x < sourceFastBitmap.Width; x++)
{
Color color;
if (!(sourceFastBitmap is IFastBitmapWithBlend sourceFastBitmapWithBlend))
{
color = sourceFastBitmap.GetColorAt(x, y);
}
else
{
color = sourceFastBitmapWithBlend.GetBlendedColorAt(x, y);
}
// To count the colors
var index = color.ToArgb() & 0x00ffffff;
// Check if we already have this color
if (!bitArray.Get(index))
{
// If not, add 1 to the single colors
_colorCount++;
bitArray.Set(index, true);
}
var indexRed = (color.R >> 3) + 1;
var indexGreen = (color.G >> 3) + 1;
var indexBlue = (color.B >> 3) + 1;
var indexRed = (color.R >> 3) + 1;
var indexGreen = (color.G >> 3) + 1;
var indexBlue = (color.B >> 3) + 1;
_weights[indexRed, indexGreen, indexBlue]++;
_momentsRed[indexRed, indexGreen, indexBlue] += color.R;
_momentsGreen[indexRed, indexGreen, indexBlue] += color.G;
_momentsBlue[indexRed, indexGreen, indexBlue] += color.B;
_moments[indexRed, indexGreen, indexBlue] += table[color.R] + table[color.G] + table[color.B];
_weights[indexRed, indexGreen, indexBlue]++;
_momentsRed[indexRed, indexGreen, indexBlue] += color.R;
_momentsGreen[indexRed, indexGreen, indexBlue] += color.G;
_momentsBlue[indexRed, indexGreen, indexBlue] += color.B;
_moments[indexRed, indexGreen, indexBlue] += table[color.R] + table[color.G] + table[color.B];
// Store the initial "match"
var paletteIndex = (indexRed << 10) + (indexRed << 6) + indexRed + (indexGreen << 5) + indexGreen + indexBlue;
destinationFastBitmap.SetColorIndexAt(x, y, (byte) (paletteIndex & 0xff));
}
}
_resultBitmap = destinationFastBitmap.UnlockAndReturnBitmap();
}
}
}
// Store the initial "match"
var paletteIndex = (indexRed << 10) + (indexRed << 6) + indexRed + (indexGreen << 5) + indexGreen + indexBlue;
destinationFastBitmap.SetColorIndexAt(x, y, (byte) (paletteIndex & 0xff));
}
}
_resultBitmap = destinationFastBitmap.UnlockAndReturnBitmap();
}
/// <inheritdoc/>
public void Dispose()
@ -200,38 +196,36 @@ namespace Greenshot.Gfx.Quantizer
using (var bbbDest = FastBitmapFactory.Create(_resultBitmap) as FastChunkyBitmap)
{
bbbDest.Lock();
using (var bbbSrc = FastBitmapFactory.Create(_sourceBitmap))
{
bbbSrc.Lock();
for (var y = 0; y < bbbSrc.Height; y++)
{
for (var x = 0; x < bbbSrc.Width; x++)
{
Color color;
if (bbbSrc is IFastBitmapWithBlend bbbSrcBlend)
{
color = bbbSrcBlend.GetBlendedColorAt(x, y);
}
else
{
color = bbbSrc.GetColorAt(x, y);
}
byte index;
if (lookup.ContainsKey(color))
{
index = lookup[color];
}
else
{
colors.Add(color);
index = (byte) (colors.Count - 1);
lookup.Add(color, index);
}
bbbDest.SetColorIndexAt(x, y, index);
}
}
}
}
using var bbbSrc = FastBitmapFactory.Create(_sourceBitmap);
bbbSrc.Lock();
for (var y = 0; y < bbbSrc.Height; y++)
{
for (var x = 0; x < bbbSrc.Width; x++)
{
Color color;
if (bbbSrc is IFastBitmapWithBlend bbbSrcBlend)
{
color = bbbSrcBlend.GetBlendedColorAt(x, y);
}
else
{
color = bbbSrc.GetColorAt(x, y);
}
byte index;
if (lookup.ContainsKey(color))
{
index = lookup[color];
}
else
{
colors.Add(color);
index = (byte) (colors.Count - 1);
lookup.Add(color, index);
}
bbbDest.SetColorIndexAt(x, y, index);
}
}
}
// generates palette
var imagePalette = _resultBitmap.NativeBitmap.Palette;
@ -348,71 +342,69 @@ namespace Greenshot.Gfx.Quantizer
Log.Info().WriteLine("Starting bitmap reconstruction...");
using (var dest = FastBitmapFactory.Create(_resultBitmap) as FastChunkyBitmap)
{
using (var src = FastBitmapFactory.Create(_sourceBitmap))
{
var lookup = new Dictionary<Color, byte>();
for (var y = 0; y < src.Height; y++)
{
for (var x = 0; x < src.Width; x++)
{
Color color;
if (src is IFastBitmapWithBlend srcBlend)
{
// WithoutAlpha, this makes it possible to ignore the alpha
color = srcBlend.GetBlendedColorAt(x, y);
}
else
{
color = src.GetColorAt(x, y);
}
{
using var src = FastBitmapFactory.Create(_sourceBitmap);
var lookup = new Dictionary<Color, byte>();
for (var y = 0; y < src.Height; y++)
{
for (var x = 0; x < src.Width; x++)
{
Color color;
if (src is IFastBitmapWithBlend srcBlend)
{
// WithoutAlpha, this makes it possible to ignore the alpha
color = srcBlend.GetBlendedColorAt(x, y);
}
else
{
color = src.GetColorAt(x, y);
}
// Check if we already matched the color
byte bestMatch;
if (!lookup.ContainsKey(color))
{
// If not we need to find the best match
// Check if we already matched the color
byte bestMatch;
if (!lookup.ContainsKey(color))
{
// If not we need to find the best match
// First get initial match
bestMatch = dest.GetColorIndexAt(x, y);
bestMatch = _tag[bestMatch];
// First get initial match
bestMatch = dest.GetColorIndexAt(x, y);
bestMatch = _tag[bestMatch];
var bestDistance = 100000000;
for (var lookupIndex = 0; lookupIndex < allowedColorCount; lookupIndex++)
{
var foundRed = lookupRed[lookupIndex];
var foundGreen = lookupGreen[lookupIndex];
var foundBlue = lookupBlue[lookupIndex];
var deltaRed = color.R - foundRed;
var deltaGreen = color.G - foundGreen;
var deltaBlue = color.B - foundBlue;
var bestDistance = 100000000;
for (var lookupIndex = 0; lookupIndex < allowedColorCount; lookupIndex++)
{
var foundRed = lookupRed[lookupIndex];
var foundGreen = lookupGreen[lookupIndex];
var foundBlue = lookupBlue[lookupIndex];
var deltaRed = color.R - foundRed;
var deltaGreen = color.G - foundGreen;
var deltaBlue = color.B - foundBlue;
var distance = deltaRed * deltaRed + deltaGreen * deltaGreen + deltaBlue * deltaBlue;
var distance = deltaRed * deltaRed + deltaGreen * deltaGreen + deltaBlue * deltaBlue;
if (distance < bestDistance)
{
bestDistance = distance;
bestMatch = (byte) lookupIndex;
}
}
lookup.Add(color, bestMatch);
}
else
{
// Already matched, so we just use the lookup
bestMatch = lookup[color];
}
if (distance < bestDistance)
{
bestDistance = distance;
bestMatch = (byte) lookupIndex;
}
}
lookup.Add(color, bestMatch);
}
else
{
// Already matched, so we just use the lookup
bestMatch = lookup[color];
}
_reds[bestMatch] += color.R;
_greens[bestMatch] += color.G;
_blues[bestMatch] += color.B;
_sums[bestMatch]++;
_reds[bestMatch] += color.R;
_greens[bestMatch] += color.G;
_blues[bestMatch] += color.B;
_sums[bestMatch]++;
dest.SetColorIndexAt(x, y, bestMatch);
}
}
}
}
dest.SetColorIndexAt(x, y, bestMatch);
}
}
}
// generates palette
@ -524,63 +516,46 @@ namespace Greenshot.Gfx.Quantizer
/// <summary>
/// Splits the cube in given position, and color direction.
/// </summary>
private static long Top(WuColorCube cube, int direction, int position, long[,,] moment)
{
switch (direction)
{
case Red:
return moment[position, cube.GreenMaximum, cube.BlueMaximum] -
moment[position, cube.GreenMaximum, cube.BlueMinimum] -
moment[position, cube.GreenMinimum, cube.BlueMaximum] +
moment[position, cube.GreenMinimum, cube.BlueMinimum];
private static long Top(WuColorCube cube, int direction, int position, long[,,] moment) =>
direction switch
{
Red => (moment[position, cube.GreenMaximum, cube.BlueMaximum] -
moment[position, cube.GreenMaximum, cube.BlueMinimum] -
moment[position, cube.GreenMinimum, cube.BlueMaximum] +
moment[position, cube.GreenMinimum, cube.BlueMinimum]),
Green => (moment[cube.RedMaximum, position, cube.BlueMaximum] -
moment[cube.RedMaximum, position, cube.BlueMinimum] -
moment[cube.RedMinimum, position, cube.BlueMaximum] +
moment[cube.RedMinimum, position, cube.BlueMinimum]),
Blue => (moment[cube.RedMaximum, cube.GreenMaximum, position] -
moment[cube.RedMaximum, cube.GreenMinimum, position] -
moment[cube.RedMinimum, cube.GreenMaximum, position] +
moment[cube.RedMinimum, cube.GreenMinimum, position]),
_ => 0
};
case Green:
return moment[cube.RedMaximum, position, cube.BlueMaximum] -
moment[cube.RedMaximum, position, cube.BlueMinimum] -
moment[cube.RedMinimum, position, cube.BlueMaximum] +
moment[cube.RedMinimum, position, cube.BlueMinimum];
case Blue:
return moment[cube.RedMaximum, cube.GreenMaximum, position] -
moment[cube.RedMaximum, cube.GreenMinimum, position] -
moment[cube.RedMinimum, cube.GreenMaximum, position] +
moment[cube.RedMinimum, cube.GreenMinimum, position];
default:
return 0;
}
}
/// <summary>
/// <summary>
/// Splits the cube in a given color direction at its minimum.
/// </summary>
private static long Bottom(WuColorCube cube, int direction, long[,,] moment)
{
switch (direction)
{
case Red:
return -moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMaximum] +
moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] +
moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum] -
moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum];
private static long Bottom(WuColorCube cube, int direction, long[,,] moment) =>
direction switch
{
Red => (-moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMaximum] +
moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] +
moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum] -
moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum]),
Green => (-moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMaximum] +
moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] +
moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum] -
moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum]),
Blue => (-moment[cube.RedMaximum, cube.GreenMaximum, cube.BlueMinimum] +
moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] +
moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] -
moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum]),
_ => 0
};
case Green:
return -moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMaximum] +
moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] +
moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum] -
moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum];
case Blue:
return -moment[cube.RedMaximum, cube.GreenMaximum, cube.BlueMinimum] +
moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] +
moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] -
moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum];
default:
return 0;
}
}
/// <summary>
/// <summary>
/// Calculates statistical variance for a given cube.
/// </summary>
private float CalculateVariance(WuColorCube cube)

View file

@ -36,56 +36,54 @@ namespace Greenshot.Gfx
/// <param name="original">Bitmap to scale 2x</param>
public static IBitmapWithNativeSupport Scale2X(IBitmapWithNativeSupport original)
{
using (var source = (IFastBitmapWithClip)FastBitmapFactory.Create(original))
using (var destination = (IFastBitmapWithClip)FastBitmapFactory.CreateEmpty(new Size(original.Width << 1, original.Height << 1), original.PixelFormat))
using var source = (IFastBitmapWithClip)FastBitmapFactory.Create(original);
using var destination = (IFastBitmapWithClip)FastBitmapFactory.CreateEmpty(new Size(original.Width << 1, original.Height << 1), original.PixelFormat);
// Every pixel from input texture produces 4 output pixels, for more details check out http://scale2x.sourceforge.net/algorithm.html
Parallel.For(0, source.Height, y =>
{
// Every pixel from input texture produces 4 output pixels, for more details check out http://scale2x.sourceforge.net/algorithm.html
Parallel.For(0, source.Height, y =>
unsafe
{
unsafe
var colorB = stackalloc byte[4];
var colorD = stackalloc byte[4];
var colorE = stackalloc byte[4];
var colorF = stackalloc byte[4];
var colorH = stackalloc byte[4];
var x = 0;
while (x < source.Width)
{
var colorB = stackalloc byte[4];
var colorD = stackalloc byte[4];
var colorE = stackalloc byte[4];
var colorF = stackalloc byte[4];
var colorH = stackalloc byte[4];
var x = 0;
while (x < source.Width)
source.GetColorAt(x, y - 1, colorB);
source.GetColorAt(x, y + 1, colorH);
source.GetColorAt(x - 1, y, colorD);
source.GetColorAt(x + 1, y, colorF);
source.GetColorAt(x, y, colorE);
byte* colorE0, colorE1, colorE2, colorE3;
if (!AreColorsSame(colorB, colorH) && !AreColorsSame(colorD, colorF))
{
source.GetColorAt(x, y - 1, colorB);
source.GetColorAt(x, y + 1, colorH);
source.GetColorAt(x - 1, y, colorD);
source.GetColorAt(x + 1, y, colorF);
source.GetColorAt(x, y, colorE);
byte* colorE0, colorE1, colorE2, colorE3;
if (!AreColorsSame(colorB, colorH) && !AreColorsSame(colorD, colorF))
{
colorE0 = AreColorsSame(colorD, colorB) ? colorD : colorE;
colorE1 = AreColorsSame(colorB, colorF) ? colorF : colorE;
colorE2 = AreColorsSame(colorD, colorH) ? colorD : colorE;
colorE3 = AreColorsSame(colorH, colorF) ? colorF : colorE;
}
else
{
colorE0 = colorE;
colorE1 = colorE;
colorE2 = colorE;
colorE3 = colorE;
}
destination.SetColorAt(x << 1, y << 1, colorE0);
destination.SetColorAt((x << 1) + 1, y << 1, colorE1);
destination.SetColorAt(x << 1, (y << 1) + 1, colorE2);
destination.SetColorAt((x << 1) + 1, (y << 1) + 1, colorE3);
x++;
colorE0 = AreColorsSame(colorD, colorB) ? colorD : colorE;
colorE1 = AreColorsSame(colorB, colorF) ? colorF : colorE;
colorE2 = AreColorsSame(colorD, colorH) ? colorD : colorE;
colorE3 = AreColorsSame(colorH, colorF) ? colorF : colorE;
}
else
{
colorE0 = colorE;
colorE1 = colorE;
colorE2 = colorE;
colorE3 = colorE;
}
destination.SetColorAt(x << 1, y << 1, colorE0);
destination.SetColorAt((x << 1) + 1, y << 1, colorE1);
destination.SetColorAt(x << 1, (y << 1) + 1, colorE2);
destination.SetColorAt((x << 1) + 1, (y << 1) + 1, colorE3);
x++;
}
});
return destination.UnlockAndReturnBitmap();
}
}
});
return destination.UnlockAndReturnBitmap();
}
/// <summary>
@ -95,89 +93,87 @@ namespace Greenshot.Gfx
[SuppressMessage("ReSharper", "AccessToDisposedClosure")]
public static IBitmapWithNativeSupport Scale3X(IBitmapWithNativeSupport original)
{
using (var source = (IFastBitmapWithClip)FastBitmapFactory.Create(original))
using (var destination = (IFastBitmapWithClip)FastBitmapFactory.CreateEmpty(new Size(original.Width * 3, original.Height * 3), original.PixelFormat))
using var source = (IFastBitmapWithClip)FastBitmapFactory.Create(original);
using var destination = (IFastBitmapWithClip)FastBitmapFactory.CreateEmpty(new Size(original.Width * 3, original.Height * 3), original.PixelFormat);
// Every pixel from input texture produces 6 output pixels, for more details check out http://scale2x.sourceforge.net/algorithm.html
Parallel.For(0, source.Height, y =>
{
// Every pixel from input texture produces 6 output pixels, for more details check out http://scale2x.sourceforge.net/algorithm.html
Parallel.For(0, source.Height, y =>
unsafe
{
unsafe
var x = 0;
var colorA = stackalloc byte[4];
var colorB = stackalloc byte[4];
var colorC = stackalloc byte[4];
var colorD = stackalloc byte[4];
var colorE = stackalloc byte[4];
var colorF = stackalloc byte[4];
var colorG = stackalloc byte[4];
var colorH = stackalloc byte[4];
var colorI = stackalloc byte[4];
while (x < source.Width)
{
var x = 0;
var colorA = stackalloc byte[4];
var colorB = stackalloc byte[4];
var colorC = stackalloc byte[4];
var colorD = stackalloc byte[4];
var colorE = stackalloc byte[4];
var colorF = stackalloc byte[4];
var colorG = stackalloc byte[4];
var colorH = stackalloc byte[4];
var colorI = stackalloc byte[4];
while (x < source.Width)
source.GetColorAt(x - 1, y - 1, colorA);
source.GetColorAt(x, y - 1, colorB);
source.GetColorAt(x + 1, y - 1, colorC);
source.GetColorAt(x - 1, y, colorD);
source.GetColorAt(x, y, colorE);
source.GetColorAt(x + 1, y, colorF);
source.GetColorAt(x - 1, y + 1, colorG);
source.GetColorAt(x, y + 1, colorH);
source.GetColorAt(x + 1, y + 1, colorI);
byte* colorE0, colorE1, colorE2, colorE3, colorE4, colorE5, colorE6, colorE7, colorE8;
if (!AreColorsSame(colorB, colorH) && !AreColorsSame(colorD, colorF))
{
source.GetColorAt(x - 1, y - 1, colorA);
source.GetColorAt(x, y - 1, colorB);
source.GetColorAt(x + 1, y - 1, colorC);
colorE0 = AreColorsSame(colorD, colorB) ? colorD : colorE;
colorE1 = AreColorsSame(colorD, colorB) && !AreColorsSame(colorE, colorC) || AreColorsSame(colorB, colorF) && !AreColorsSame(colorE, colorA) ? colorB : colorE;
colorE2 = AreColorsSame(colorB, colorF) ? colorF : colorE;
colorE3 = AreColorsSame(colorD, colorB) && !AreColorsSame(colorE, colorG) || AreColorsSame(colorD, colorH) && !AreColorsSame(colorE, colorA) ? colorD : colorE;
source.GetColorAt(x - 1, y, colorD);
source.GetColorAt(x, y, colorE);
source.GetColorAt(x + 1, y, colorF);
source.GetColorAt(x - 1, y + 1, colorG);
source.GetColorAt(x, y + 1, colorH);
source.GetColorAt(x + 1, y + 1, colorI);
byte* colorE0, colorE1, colorE2, colorE3, colorE4, colorE5, colorE6, colorE7, colorE8;
if (!AreColorsSame(colorB, colorH) && !AreColorsSame(colorD, colorF))
{
colorE0 = AreColorsSame(colorD, colorB) ? colorD : colorE;
colorE1 = AreColorsSame(colorD, colorB) && !AreColorsSame(colorE, colorC) || AreColorsSame(colorB, colorF) && !AreColorsSame(colorE, colorA) ? colorB : colorE;
colorE2 = AreColorsSame(colorB, colorF) ? colorF : colorE;
colorE3 = AreColorsSame(colorD, colorB) && !AreColorsSame(colorE, colorG) || AreColorsSame(colorD, colorH) && !AreColorsSame(colorE, colorA) ? colorD : colorE;
colorE4 = colorE;
colorE5 = AreColorsSame(colorB, colorF) && !AreColorsSame(colorE, colorI) || AreColorsSame(colorH, colorF) && !AreColorsSame(colorE, colorC) ? colorF : colorE;
colorE6 = AreColorsSame(colorD, colorH) ? colorD : colorE;
colorE7 = AreColorsSame(colorD, colorH) && !AreColorsSame(colorE, colorI) || AreColorsSame(colorH, colorF) && !AreColorsSame(colorE, colorG) ? colorH : colorE;
colorE8 = AreColorsSame(colorH, colorF) ? colorF : colorE;
}
else
{
colorE0 = colorE;
colorE1 = colorE;
colorE2 = colorE;
colorE3 = colorE;
colorE4 = colorE;
colorE5 = colorE;
colorE6 = colorE;
colorE7 = colorE;
colorE8 = colorE;
}
var multipliedX = 3 * x;
var multipliedY = 3 * y;
destination.SetColorAt(multipliedX, multipliedY, colorE0);
destination.SetColorAt(multipliedX + 1, multipliedY, colorE1);
destination.SetColorAt(multipliedX + 2, multipliedY, colorE2);
multipliedY++;
destination.SetColorAt(multipliedX, multipliedY, colorE3);
destination.SetColorAt(multipliedX + 1, multipliedY, colorE4);
destination.SetColorAt(multipliedX + 2, multipliedY, colorE5);
multipliedY++;
destination.SetColorAt(multipliedX, multipliedY, colorE6);
destination.SetColorAt(multipliedX + 1, multipliedY, colorE7);
destination.SetColorAt(multipliedX + 2, multipliedY, colorE8);
x++;
colorE4 = colorE;
colorE5 = AreColorsSame(colorB, colorF) && !AreColorsSame(colorE, colorI) || AreColorsSame(colorH, colorF) && !AreColorsSame(colorE, colorC) ? colorF : colorE;
colorE6 = AreColorsSame(colorD, colorH) ? colorD : colorE;
colorE7 = AreColorsSame(colorD, colorH) && !AreColorsSame(colorE, colorI) || AreColorsSame(colorH, colorF) && !AreColorsSame(colorE, colorG) ? colorH : colorE;
colorE8 = AreColorsSame(colorH, colorF) ? colorF : colorE;
}
else
{
colorE0 = colorE;
colorE1 = colorE;
colorE2 = colorE;
colorE3 = colorE;
colorE4 = colorE;
colorE5 = colorE;
colorE6 = colorE;
colorE7 = colorE;
colorE8 = colorE;
}
var multipliedX = 3 * x;
var multipliedY = 3 * y;
destination.SetColorAt(multipliedX, multipliedY, colorE0);
destination.SetColorAt(multipliedX + 1, multipliedY, colorE1);
destination.SetColorAt(multipliedX + 2, multipliedY, colorE2);
multipliedY++;
destination.SetColorAt(multipliedX, multipliedY, colorE3);
destination.SetColorAt(multipliedX + 1, multipliedY, colorE4);
destination.SetColorAt(multipliedX + 2, multipliedY, colorE5);
multipliedY++;
destination.SetColorAt(multipliedX, multipliedY, colorE6);
destination.SetColorAt(multipliedX + 1, multipliedY, colorE7);
destination.SetColorAt(multipliedX + 2, multipliedY, colorE8);
x++;
}
});
return destination.UnlockAndReturnBitmap();
}
}
});
return destination.UnlockAndReturnBitmap();
}
/// <summary>

View file

@ -133,24 +133,14 @@ namespace Greenshot.Gfx
{
get
{
PixelFormat format;
TPixelLayout empty = default;
switch (empty)
return empty switch
{
case Bgr24 _:
format = PixelFormat.Format24bppRgb;
break;
case Bgra32 _:
format = PixelFormat.Format32bppArgb;
break;
case Bgr32 _:
format = PixelFormat.Format32bppRgb;
break;
default:
throw new NotSupportedException("Unknown pixel format");
}
return format;
Bgr24 _ => PixelFormat.Format24bppRgb,
Bgra32 _ => PixelFormat.Format32bppArgb,
Bgr32 _ => PixelFormat.Format32bppRgb,
_ => throw new NotSupportedException("Unknown pixel format")
};
}
}
@ -162,17 +152,13 @@ namespace Greenshot.Gfx
get
{
TPixelLayout empty = default;
switch (empty)
return empty switch
{
case Bgr24 _:
return PixelFormats.Bgr24;
case Bgra32 _:
return PixelFormats.Bgra32;
case Bgr32 _:
return PixelFormats.Bgr32;
default:
throw new NotSupportedException("Unknown pixel format");
}
Bgr24 _ => PixelFormats.Bgr24,
Bgra32 _ => PixelFormats.Bgra32,
Bgr32 _ => PixelFormats.Bgr32,
_ => throw new NotSupportedException("Unknown pixel format")
};
}
}

View file

@ -18,7 +18,6 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Drawing.Imaging;
using System.IO;
using BenchmarkDotNet.Attributes;
using Dapplo.Log;
@ -75,16 +74,14 @@ namespace Greenshot.PerformanceTests
//[Benchmark]
public void Capture()
{
using (var capture = WindowCapture.CaptureScreen())
using var capture = WindowCapture.CaptureScreen();
if (capture.Bitmap == null)
{
if (capture.Bitmap == null)
{
throw new NotSupportedException();
}
if (capture.Bitmap.Width <= 0 || capture.Bitmap.Height <= 0)
{
throw new NotSupportedException();
}
throw new NotSupportedException();
}
if (capture.Bitmap.Width <= 0 || capture.Bitmap.Height <= 0)
{
throw new NotSupportedException();
}
}

View file

@ -40,11 +40,9 @@ namespace Greenshot.PerformanceTests
{
_unmanagedTestBitmap = new UnmanagedBitmap<Bgr32>(400, 400);
_unmanagedTestBitmap.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255, Unused = 0});
using (var graphics = Graphics.FromImage(_unmanagedTestBitmap.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
using var graphics = Graphics.FromImage(_unmanagedTestBitmap.NativeBitmap);
using var pen = new SolidBrush(Color.Blue);
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
[GlobalCleanup]
@ -60,19 +58,16 @@ namespace Greenshot.PerformanceTests
[Arguments(PixelFormat.Format32bppArgb)]
public void WuQuantizer(PixelFormat pixelFormat)
{
using (var bitmap = BitmapFactory.CreateEmpty(400, 400, pixelFormat, Color.White))
using var bitmap = BitmapFactory.CreateEmpty(400, 400, pixelFormat, Color.White);
using (var graphics = Graphics.FromImage(bitmap.NativeBitmap))
{
using (var graphics = Graphics.FromImage(bitmap.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
var quantizer = new WuQuantizer(bitmap);
using (var quantizedImage = quantizer.GetQuantizedImage())
{
quantizedImage.NativeBitmap.Save(@"quantized.png", ImageFormat.Png);
}
using var pen = new SolidBrush(Color.Blue);
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
var quantizer = new WuQuantizer(bitmap);
using var quantizedImage = quantizer.GetQuantizedImage();
quantizedImage.NativeBitmap.Save(@"quantized.png", ImageFormat.Png);
}
[Benchmark]
@ -81,45 +76,41 @@ namespace Greenshot.PerformanceTests
[Arguments(PixelFormat.Format32bppArgb)]
public void Blur_FastBitmap(PixelFormat pixelFormat)
{
using (var bitmap = BitmapFactory.CreateEmpty(400, 400, pixelFormat, Color.White))
using var bitmap = BitmapFactory.CreateEmpty(400, 400, pixelFormat, Color.White);
using (var graphics = Graphics.FromImage(bitmap.NativeBitmap))
{
using (var graphics = Graphics.FromImage(bitmap.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
bitmap.ApplyBoxBlur(10);
using var pen = new SolidBrush(Color.Blue);
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
bitmap.ApplyBoxBlur(10);
}
[Benchmark]
public void Blur_UnmanagedBitmap()
{
using (var unmanagedBitmap = new UnmanagedBitmap<Bgr32>(400, 400))
using var unmanagedBitmap = new UnmanagedBitmap<Bgr32>(400, 400);
unmanagedBitmap.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255 });
using (var graphics = Graphics.FromImage(unmanagedBitmap.NativeBitmap))
{
unmanagedBitmap.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255 });
using (var graphics = Graphics.FromImage(unmanagedBitmap.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
unmanagedBitmap.ApplyBoxBlur(10);
using var pen = new SolidBrush(Color.Blue);
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
unmanagedBitmap.ApplyBoxBlur(10);
}
[Benchmark]
public void Blur_Old()
{
using (var bitmap = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format32bppRgb, Color.White))
using var bitmap = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format32bppRgb, Color.White);
using (var graphics = Graphics.FromImage(bitmap.NativeBitmap))
{
using (var graphics = Graphics.FromImage(bitmap.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
BoxBlurOld.ApplyOldBoxBlur(bitmap, 10);
using var pen = new SolidBrush(Color.Blue);
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
BoxBlurOld.ApplyOldBoxBlur(bitmap, 10);
}
[Benchmark]

View file

@ -16,9 +16,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.11.5" />
<PackageReference Include="BenchmarkDotNet" Version="0.12.0" />
<PackageReference Include="CommandLineParser" Version="2.6.0" />
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="3.0.0" />
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="3.1.0" />
<PackageReference Include="SharpAvi" Version="2.1.2" />
<PackageReference Include="System.Memory" Version="4.5.3" />
</ItemGroup>

View file

@ -37,54 +37,54 @@ namespace Greenshot.Tests
[InlineData(PixelFormat.Format32bppArgb)]
public void Test_Blur(PixelFormat pixelFormat)
{
using (var bitmapNew = BitmapFactory.CreateEmpty(400, 400, pixelFormat, Color.White))
using (var bitmapOld = BitmapFactory.CreateEmpty(400, 400, pixelFormat, Color.White))
using var bitmapNew = BitmapFactory.CreateEmpty(400, 400, pixelFormat, Color.White);
using var bitmapOld = BitmapFactory.CreateEmpty(400, 400, pixelFormat, Color.White);
using (var graphics = Graphics.FromImage(bitmapNew.NativeBitmap))
{
using (var graphics = Graphics.FromImage(bitmapNew.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
bitmapNew.ApplyBoxBlur(10);
}
using (var graphics = Graphics.FromImage(bitmapOld.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
BoxBlurOld.ApplyOldBoxBlur(bitmapOld, 10);
}
bitmapOld.NativeBitmap.Save(@"old.png", ImageFormat.Png);
bitmapNew.NativeBitmap.Save(@"new.png", ImageFormat.Png);
Assert.True(bitmapOld.IsEqualTo(bitmapNew), "New blur doesn't compare to old.");
using var pen = new SolidBrush(Color.Blue);
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
bitmapNew.ApplyBoxBlur(10);
}
using (var graphics = Graphics.FromImage(bitmapOld.NativeBitmap))
{
using var pen = new SolidBrush(Color.Blue);
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
BoxBlurOld.ApplyOldBoxBlur(bitmapOld, 10);
}
bitmapOld.NativeBitmap.Save(@"old.png", ImageFormat.Png);
bitmapNew.NativeBitmap.Save(@"new.png", ImageFormat.Png);
Assert.True(bitmapOld.IsEqualTo(bitmapNew), "New blur doesn't compare to old.");
}
[Fact]
public void Test_Blur_UnmanagedBitmap()
{
using (var bitmapNew = new UnmanagedBitmap<Bgr32>(400, 400))
using (var bitmapOld = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format32bppRgb, Color.White))
using var bitmapNew = new UnmanagedBitmap<Bgr32>(400, 400);
using var bitmapOld = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format32bppRgb, Color.White);
using (var graphics = Graphics.FromImage(bitmapOld.NativeBitmap))
{
using (var graphics = Graphics.FromImage(bitmapOld.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
BoxBlurOld.ApplyOldBoxBlur(bitmapOld, 10);
bitmapOld.NativeBitmap.Save(@"old.png", ImageFormat.Png);
bitmapNew.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255 });
using (var graphics = Graphics.FromImage(bitmapNew.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
bitmapNew.ApplyBoxBlur(10);
bitmapNew.NativeBitmap.Save(@"new.png", ImageFormat.Png);
Assert.True(bitmapOld.IsEqualTo(bitmapNew), "New blur doesn't compare to old.");
using var pen = new SolidBrush(Color.Blue);
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
BoxBlurOld.ApplyOldBoxBlur(bitmapOld, 10);
bitmapOld.NativeBitmap.Save(@"old.png", ImageFormat.Png);
bitmapNew.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255 });
using (var graphics = Graphics.FromImage(bitmapNew.NativeBitmap))
{
using var pen = new SolidBrush(Color.Blue);
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
bitmapNew.ApplyBoxBlur(10);
bitmapNew.NativeBitmap.Save(@"new.png", ImageFormat.Png);
Assert.True(bitmapOld.IsEqualTo(bitmapNew), "New blur doesn't compare to old.");
}
}
}

View file

@ -86,12 +86,11 @@ namespace Greenshot.Tests
[Fact]
public void Test_GdiScreenCapture()
{
using (var gdiScreenCapture = new GdiScreenCapture())
using var gdiScreenCapture = new GdiScreenCapture();
gdiScreenCapture.CaptureFrame();
using (var bitmap = gdiScreenCapture.CurrentFrameAsBitmap())
{
gdiScreenCapture.CaptureFrame();
using (var bitmap = gdiScreenCapture.CurrentFrameAsBitmap())
{
Assert.True(bitmap.Width > 0);
Assert.True(bitmap.Width > 0);
/*
// Write the capture to a file, for analysis
@ -100,13 +99,12 @@ namespace Greenshot.Tests
ImageOutput.SaveToStream(bitmap, null, stream, new SurfaceOutputSettings(null, OutputFormats.png));
}
*/
}
var bitmapSource = gdiScreenCapture.CurrentFrameAsBitmapSource();
Assert.True(bitmapSource.Width > 0);
gdiScreenCapture.CaptureFrame();
}
var bitmapSource = gdiScreenCapture.CurrentFrameAsBitmapSource();
Assert.True(bitmapSource.Width > 0);
gdiScreenCapture.CaptureFrame();
}
/// <summary>
@ -144,11 +142,12 @@ namespace Greenshot.Tests
var template = new SimpleTemplate();
var bitmapSource = template.Apply(capture).ToBitmapSource();
using (var outputStream = bitmapSource.ToStream(OutputFormats.png))
using (var fileStream = File.Create("Test_CaptureFlow_DwmWindowSource.png"))
{
using var fileStream = File.Create("Test_CaptureFlow_DwmWindowSource.png");
outputStream.Seek(0, SeekOrigin.Begin);
await outputStream.CopyToAsync(fileStream);
}
Assert.Equal(bounds.Size, bitmapSource.Size());
}
@ -159,26 +158,22 @@ namespace Greenshot.Tests
[Fact]
public void Test_BitmapCapture()
{
using (var screenBitmapCapture = new BitmapScreenCapture())
using var screenBitmapCapture = new BitmapScreenCapture();
screenBitmapCapture.CaptureFrame();
Assert.NotNull(screenBitmapCapture.CurrentFrameAsBitmap());
var testFile1 = Path.Combine(Path.GetTempPath(), @"test-bitmap.png");
screenBitmapCapture.CurrentFrameAsBitmap().NativeBitmap.Save(testFile1, ImageFormat.Png);
var testFile2 = Path.Combine(Path.GetTempPath(), @"test-bitmapsource.png");
using var fileStream = new FileStream(testFile2, FileMode.Create);
var encoder = new PngBitmapEncoder
{
screenBitmapCapture.CaptureFrame();
Assert.NotNull(screenBitmapCapture.CurrentFrameAsBitmap());
var testFile1 = Path.Combine(Path.GetTempPath(), @"test-bitmap.png");
screenBitmapCapture.CurrentFrameAsBitmap().NativeBitmap.Save(testFile1, ImageFormat.Png);
var testFile2 = Path.Combine(Path.GetTempPath(), @"test-bitmapsource.png");
using (var fileStream = new FileStream(testFile2, FileMode.Create))
{
var encoder = new PngBitmapEncoder
{
Interlace = PngInterlaceOption.Off
};
encoder.Frames.Add(BitmapFrame.Create(screenBitmapCapture.CurrentFrameAsBitmap().NativeBitmapSource));
encoder.Save(fileStream);
}
}
Interlace = PngInterlaceOption.Off
};
encoder.Frames.Add(BitmapFrame.Create(screenBitmapCapture.CurrentFrameAsBitmap().NativeBitmapSource));
encoder.Save(fileStream);
}
}
}

View file

@ -19,27 +19,27 @@ namespace Greenshot.Tests
[Fact]
public void TestBlur()
{
using (var bitmap1 = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format24bppRgb, Color.White))
using (var bitmap2 = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format24bppRgb, Color.White))
using var bitmap1 = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format24bppRgb, Color.White);
using var bitmap2 = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format24bppRgb, Color.White);
using (var graphics = Graphics.FromImage(bitmap1.NativeBitmap))
{
using (var graphics = Graphics.FromImage(bitmap1.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
bitmap1.NativeBitmap.Save("bitmap0.png", ImageFormat.Png);
bitmap1.ApplyBoxBlur(10);
bitmap1.NativeBitmap.Save("bitmap1.png", ImageFormat.Png);
using (var graphics = Graphics.FromImage(bitmap2.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
BoxBlurOld.ApplyOldBoxBlur(bitmap2, 10);
bitmap2.NativeBitmap.Save("bitmap2.png", ImageFormat.Png);
Assert.True(bitmap1.IsEqualTo(bitmap2));
using var pen = new SolidBrush(Color.Blue);
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
bitmap1.NativeBitmap.Save("bitmap0.png", ImageFormat.Png);
bitmap1.ApplyBoxBlur(10);
bitmap1.NativeBitmap.Save("bitmap1.png", ImageFormat.Png);
using (var graphics = Graphics.FromImage(bitmap2.NativeBitmap))
{
using var pen = new SolidBrush(Color.Blue);
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
BoxBlurOld.ApplyOldBoxBlur(bitmap2, 10);
bitmap2.NativeBitmap.Save("bitmap2.png", ImageFormat.Png);
Assert.True(bitmap1.IsEqualTo(bitmap2));
}
}
}

View file

@ -28,7 +28,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.11.5" />
<PackageReference Include="BenchmarkDotNet" Version="0.12.0" />
<PackageReference Include="CommandLineParser" Version="2.6.0" />
<PackageReference Include="Dapplo.Log.XUnit" Version="1.3.26" />
<PackageReference Include="Dapplo.Windows" Version="0.11.6" />

View file

@ -18,10 +18,8 @@ namespace Greenshot.Tests.Implementation
public static void ApplyOldBoxBlur(this IBitmapWithNativeSupport destinationBitmap, int range)
{
// We only need one fastbitmap as we use it as source and target (the reading is done for one line H/V, writing after "parsing" one line H/V)
using (var fastBitmap = FastBitmapFactory.Create(destinationBitmap))
{
fastBitmap.ApplyOldBoxBlur(range);
}
using var fastBitmap = FastBitmapFactory.Create(destinationBitmap);
fastBitmap.ApplyOldBoxBlur(range);
}
/// <summary>

Some files were not shown because too many files have changed in this diff Show more