mirror of
https://github.com/greenshot/greenshot
synced 2025-08-22 22:34:27 -07:00
Made image file format support extensible by providing a new interface IImageFormatReader and supplying some implementations.
This commit is contained in:
parent
66c919098d
commit
694e2f3f4d
11 changed files with 323 additions and 149 deletions
|
@ -13,5 +13,6 @@
|
||||||
<add key="aspnet-entityframeworkcore" value="https://dotnetfeed.blob.core.windows.net/aspnet-entityframeworkcore/index.json" />
|
<add key="aspnet-entityframeworkcore" value="https://dotnetfeed.blob.core.windows.net/aspnet-entityframeworkcore/index.json" />
|
||||||
<add key="aspnet-extensions" value="https://dotnetfeed.blob.core.windows.net/aspnet-extensions/index.json" />
|
<add key="aspnet-extensions" value="https://dotnetfeed.blob.core.windows.net/aspnet-extensions/index.json" />
|
||||||
<add key="bdn-nightly" value="https://ci.appveyor.com/nuget/benchmarkdotnet" />
|
<add key="bdn-nightly" value="https://ci.appveyor.com/nuget/benchmarkdotnet" />
|
||||||
|
<add key="dotnet-core-myget" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>
|
</configuration>
|
|
@ -21,7 +21,6 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Greenshot.Addon.LegacyEditor.Forms;
|
using Greenshot.Addon.LegacyEditor.Forms;
|
||||||
using Greenshot.Addons.Core;
|
|
||||||
using Greenshot.Addons.Interfaces;
|
using Greenshot.Addons.Interfaces;
|
||||||
using Greenshot.Addons.Interfaces.Forms;
|
using Greenshot.Addons.Interfaces.Forms;
|
||||||
|
|
||||||
|
@ -38,13 +37,10 @@ namespace Greenshot.Addon.LegacyEditor
|
||||||
|
|
||||||
public EditorFactory(
|
public EditorFactory(
|
||||||
IEditorConfiguration editorConfiguration,
|
IEditorConfiguration editorConfiguration,
|
||||||
Func<ImageEditorForm> imageEditorFactory,
|
Func<ImageEditorForm> imageEditorFactory)
|
||||||
Func<ISurface> surfaceExportFactory)
|
|
||||||
{
|
{
|
||||||
_editorConfiguration = editorConfiguration;
|
_editorConfiguration = editorConfiguration;
|
||||||
_imageEditorFactory = imageEditorFactory;
|
_imageEditorFactory = imageEditorFactory;
|
||||||
// Factory for surface objects
|
|
||||||
ImageOutput.SurfaceFactory = surfaceExportFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -28,6 +28,8 @@ using Greenshot.Addons.Controls;
|
||||||
using Greenshot.Addons.Core;
|
using Greenshot.Addons.Core;
|
||||||
using Greenshot.Addons.Resources;
|
using Greenshot.Addons.Resources;
|
||||||
using Greenshot.Addons.ViewModels;
|
using Greenshot.Addons.ViewModels;
|
||||||
|
using Greenshot.Gfx;
|
||||||
|
using Greenshot.Gfx.Formats;
|
||||||
|
|
||||||
namespace Greenshot.Addons
|
namespace Greenshot.Addons
|
||||||
{
|
{
|
||||||
|
@ -96,6 +98,16 @@ namespace Greenshot.Addons
|
||||||
.SingleInstance()
|
.SingleInstance()
|
||||||
.AutoActivate();
|
.AutoActivate();
|
||||||
|
|
||||||
|
builder
|
||||||
|
.RegisterType<GreenshotFormatReader>()
|
||||||
|
.As<IImageFormatReader>()
|
||||||
|
.SingleInstance()
|
||||||
|
.AutoActivate()
|
||||||
|
.OnActivated(args =>
|
||||||
|
{
|
||||||
|
BitmapHelper.StreamConverters["greenshot"] = args.Instance;
|
||||||
|
});
|
||||||
|
|
||||||
base.Load(builder);
|
base.Load(builder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
30
src/Greenshot.Addons/Core/GreenshotFormatReader.cs
Normal file
30
src/Greenshot.Addons/Core/GreenshotFormatReader.cs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using Greenshot.Addons.Interfaces;
|
||||||
|
using Greenshot.Gfx;
|
||||||
|
using Greenshot.Gfx.Formats;
|
||||||
|
|
||||||
|
namespace Greenshot.Addons.Core
|
||||||
|
{
|
||||||
|
public class GreenshotFormatReader : IImageFormatReader
|
||||||
|
{
|
||||||
|
private readonly Func<ISurface> _surfaceFactory;
|
||||||
|
|
||||||
|
public GreenshotFormatReader(Func<ISurface> surfaceFactory)
|
||||||
|
{
|
||||||
|
_surfaceFactory = surfaceFactory;
|
||||||
|
ImageOutput.SurfaceFactory = surfaceFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<string> SupportedFormats { get; } = new[] { "greenshot" };
|
||||||
|
|
||||||
|
public IBitmapWithNativeSupport Read(Stream stream, string extension = null)
|
||||||
|
{
|
||||||
|
// TODO: Create surface from stream
|
||||||
|
var surface = _surfaceFactory();
|
||||||
|
surface.LoadElementsFromStream(stream);
|
||||||
|
return surface.GetBitmapForExport();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -62,16 +62,6 @@ namespace Greenshot.Addons.Core
|
||||||
private static readonly int PROPERTY_TAG_SOFTWARE_USED = 0x0131;
|
private static readonly int PROPERTY_TAG_SOFTWARE_USED = 0x0131;
|
||||||
private static readonly Cache<string, string> TmpFileCache = new Cache<string, string>(10 * 60 * 60, RemoveExpiredTmpFile);
|
private static readonly Cache<string, string> TmpFileCache = new Cache<string, string>(10 * 60 * 60, RemoveExpiredTmpFile);
|
||||||
|
|
||||||
static ImageOutput()
|
|
||||||
{
|
|
||||||
BitmapHelper.StreamConverters["greenshot"] = (stream, s) =>
|
|
||||||
{
|
|
||||||
// TODO: Create surface from stream
|
|
||||||
var surface = SurfaceFactory();
|
|
||||||
surface.LoadElementsFromStream(stream);
|
|
||||||
return surface.GetBitmapForExport();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is a factory method to create a surface, set from the Greenshot main project
|
/// This is a factory method to create a surface, set from the Greenshot main project
|
||||||
|
@ -390,7 +380,7 @@ namespace Greenshot.Addons.Core
|
||||||
|
|
||||||
// We create a copy of the bitmap, so everything else can be disposed
|
// We create a copy of the bitmap, so everything else can be disposed
|
||||||
surfaceFileStream.Position = 0;
|
surfaceFileStream.Position = 0;
|
||||||
var fileImage = BitmapHelper.FromStreamReader(surfaceFileStream, ".greenshot");
|
var fileImage = BitmapHelper.FromStream(surfaceFileStream, ".greenshot");
|
||||||
|
|
||||||
// Start at -14 read "GreenshotXX.YY" (XX=Major, YY=Minor)
|
// Start at -14 read "GreenshotXX.YY" (XX=Major, YY=Minor)
|
||||||
const int markerSize = 14;
|
const int markerSize = 14;
|
||||||
|
|
|
@ -32,6 +32,7 @@ using Dapplo.Windows.Dpi;
|
||||||
using Greenshot.Gfx.Effects;
|
using Greenshot.Gfx.Effects;
|
||||||
using Greenshot.Gfx.Extensions;
|
using Greenshot.Gfx.Extensions;
|
||||||
using Greenshot.Gfx.FastBitmap;
|
using Greenshot.Gfx.FastBitmap;
|
||||||
|
using Greenshot.Gfx.Formats;
|
||||||
using Greenshot.Gfx.Structs;
|
using Greenshot.Gfx.Structs;
|
||||||
|
|
||||||
namespace Greenshot.Gfx
|
namespace Greenshot.Gfx
|
||||||
|
@ -44,91 +45,10 @@ namespace Greenshot.Gfx
|
||||||
private const int ExifOrientationId = 0x0112;
|
private const int ExifOrientationId = 0x0112;
|
||||||
private static readonly LogSource Log = new LogSource();
|
private static readonly LogSource Log = new LogSource();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A function which usage image.fromstream
|
|
||||||
/// </summary>
|
|
||||||
public static readonly Func<Stream, string, IBitmapWithNativeSupport> FromStreamReader = (stream, s) =>
|
|
||||||
{
|
|
||||||
using (var tmpImage = Image.FromStream(stream, true, true))
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static BitmapHelper()
|
|
||||||
{
|
|
||||||
// Fallback
|
|
||||||
StreamConverters[""] = FromStreamReader;
|
|
||||||
|
|
||||||
StreamConverters["gif"] = FromStreamReader;
|
|
||||||
StreamConverters["bmp"] = FromStreamReader;
|
|
||||||
StreamConverters["jpg"] = FromStreamReader;
|
|
||||||
StreamConverters["jpeg"] = FromStreamReader;
|
|
||||||
StreamConverters["png"] = FromStreamReader;
|
|
||||||
StreamConverters["wmf"] = FromStreamReader;
|
|
||||||
StreamConverters["svg"] = (stream, s) =>
|
|
||||||
{
|
|
||||||
stream.Position = 0;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return SvgBitmap.FromStream(stream);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error().WriteLine(ex, "Can't load SVG");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
StreamConverters["ico"] = (stream, extension) =>
|
|
||||||
{
|
|
||||||
// Icon logic, try to get the Vista icon, else the biggest possible
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (var tmpBitmap = stream.ExtractVistaIcon())
|
|
||||||
{
|
|
||||||
if (tmpBitmap != null)
|
|
||||||
{
|
|
||||||
return tmpBitmap.CloneBitmap(PixelFormat.Format32bppArgb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception vistaIconException)
|
|
||||||
{
|
|
||||||
Log.Warn().WriteLine(vistaIconException, "Can't read icon");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception iconException)
|
|
||||||
{
|
|
||||||
Log.Warn().WriteLine(iconException, "Can't read icon");
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.Position = 0;
|
|
||||||
return FromStreamReader(stream, extension);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This defines all available bitmap reader functions, registered to an "extension" is called with a stream to a IBitmap.
|
/// This defines all available bitmap reader functions, registered to an "extension" is called with a stream to a IBitmap.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IDictionary<string, Func<Stream, string, IBitmapWithNativeSupport>> StreamConverters { get; } = new Dictionary<string, Func<Stream, string, IBitmapWithNativeSupport>>(StringComparer.OrdinalIgnoreCase);
|
public static IDictionary<string, IImageFormatReader> StreamConverters { get; } = new Dictionary<string, IImageFormatReader>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Make sure the image is orientated correctly
|
/// Make sure the image is orientated correctly
|
||||||
|
@ -403,48 +323,6 @@ namespace Greenshot.Gfx
|
||||||
return fileBitmap;
|
return fileBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Based on: http://www.codeproject.com/KB/cs/IconExtractor.aspx
|
|
||||||
/// And a hint from: http://www.codeproject.com/KB/cs/IconLib.aspx
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="iconStream">Stream with the icon information</param>
|
|
||||||
/// <returns>Bitmap with the Vista Icon (256x256)</returns>
|
|
||||||
private static IBitmapWithNativeSupport ExtractVistaIcon(this Stream iconStream)
|
|
||||||
{
|
|
||||||
const int sizeIconDir = 6;
|
|
||||||
const int sizeIconDirEntry = 16;
|
|
||||||
IBitmapWithNativeSupport bmpPngExtracted = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var srcBuf = new byte[iconStream.Length];
|
|
||||||
iconStream.Read(srcBuf, 0, (int) iconStream.Length);
|
|
||||||
int iCount = BitConverter.ToInt16(srcBuf, 4);
|
|
||||||
for (var iIndex = 0; iIndex < iCount; iIndex++)
|
|
||||||
{
|
|
||||||
int iWidth = srcBuf[sizeIconDir + sizeIconDirEntry * iIndex];
|
|
||||||
int iHeight = srcBuf[sizeIconDir + sizeIconDirEntry * iIndex + 1];
|
|
||||||
if (iWidth != 0 || iHeight != 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
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! :)
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return bmpPngExtracted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Apply the effect to the bitmap
|
/// Apply the effect to the bitmap
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -893,17 +771,10 @@ namespace Greenshot.Gfx
|
||||||
}
|
}
|
||||||
|
|
||||||
IBitmapWithNativeSupport returnBitmap = null;
|
IBitmapWithNativeSupport returnBitmap = null;
|
||||||
if (StreamConverters.TryGetValue(extension ?? "", out var converter))
|
if (StreamConverters.TryGetValue(extension ?? "", out var reader))
|
||||||
{
|
{
|
||||||
returnBitmap = converter(stream, extension);
|
returnBitmap = reader.Read(stream, extension);
|
||||||
}
|
}
|
||||||
if (returnBitmap != null || converter == FromStreamReader)
|
|
||||||
{
|
|
||||||
return returnBitmap;
|
|
||||||
}
|
|
||||||
// Fallback to default converter
|
|
||||||
stream.Position = 0;
|
|
||||||
returnBitmap = FromStreamReader(stream, extension);
|
|
||||||
return returnBitmap;
|
return returnBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
34
src/Greenshot.Gfx/Formats/GenericGdiFormatReader.cs
Normal file
34
src/Greenshot.Gfx/Formats/GenericGdiFormatReader.cs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using Dapplo.Log;
|
||||||
|
|
||||||
|
namespace Greenshot.Gfx.Formats
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This implements a IImageFormatReader with the help of Gdi
|
||||||
|
/// </summary>
|
||||||
|
public class GenericGdiFormatReader : IImageFormatReader
|
||||||
|
{
|
||||||
|
private static readonly LogSource Log = new LogSource();
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IEnumerable<string> SupportedFormats { get; } = new []{ "","gif", "bmp", "jpg", "jpeg", "png", "wmf" };
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IBitmapWithNativeSupport Read(Stream stream, string extension = null)
|
||||||
|
{
|
||||||
|
using (var tmpImage = Image.FromStream(stream, true, true))
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
src/Greenshot.Gfx/Formats/IImageFormatReader.cs
Normal file
23
src/Greenshot.Gfx/Formats/IImageFormatReader.cs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Greenshot.Gfx.Formats
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Implement this interface to add reading a format to Greenshot
|
||||||
|
/// </summary>
|
||||||
|
public interface IImageFormatReader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This returns all the formats the reader supports
|
||||||
|
/// </summary>
|
||||||
|
IEnumerable<string> SupportedFormats { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// This reads a IBitmapWithNativeSupport from a stream
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">Stream</param>
|
||||||
|
/// <param name="extension">string</param>
|
||||||
|
/// <returns>IBitmapWithNativeSupport</returns>
|
||||||
|
IBitmapWithNativeSupport Read(Stream stream, string extension = null);
|
||||||
|
}
|
||||||
|
}
|
109
src/Greenshot.Gfx/Formats/IcoFormatReader.cs
Normal file
109
src/Greenshot.Gfx/Formats/IcoFormatReader.cs
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using Dapplo.Log;
|
||||||
|
|
||||||
|
namespace Greenshot.Gfx.Formats
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This implements a IImageFormatReader which reads .ico files
|
||||||
|
/// </summary>
|
||||||
|
public class IcoFormatReader : IImageFormatReader
|
||||||
|
{
|
||||||
|
private static readonly LogSource Log = new LogSource();
|
||||||
|
private readonly GenericGdiFormatReader _genericGdiFormatReader;
|
||||||
|
|
||||||
|
public IcoFormatReader(GenericGdiFormatReader genericGdiFormatReader)
|
||||||
|
{
|
||||||
|
_genericGdiFormatReader = genericGdiFormatReader;
|
||||||
|
}
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IEnumerable<string> SupportedFormats { get; } = new []{ "ico" };
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IBitmapWithNativeSupport Read(Stream stream, string extension = null)
|
||||||
|
{
|
||||||
|
// Icon logic, try to get the Vista icon, else the biggest possible
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var tmpBitmap = ExtractVistaIcon(stream))
|
||||||
|
{
|
||||||
|
if (tmpBitmap != null)
|
||||||
|
{
|
||||||
|
return tmpBitmap.CloneBitmap(PixelFormat.Format32bppArgb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception vistaIconException)
|
||||||
|
{
|
||||||
|
Log.Warn().WriteLine(vistaIconException, "Can't read icon");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception iconException)
|
||||||
|
{
|
||||||
|
Log.Warn().WriteLine(iconException, "Can't read icon");
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
return _genericGdiFormatReader.Read(stream, extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Based on: http://www.codeproject.com/KB/cs/IconExtractor.aspx
|
||||||
|
/// And a hint from: http://www.codeproject.com/KB/cs/IconLib.aspx
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="iconStream">Stream with the icon information</param>
|
||||||
|
/// <returns>Bitmap with the Vista Icon (256x256)</returns>
|
||||||
|
private static IBitmapWithNativeSupport ExtractVistaIcon(Stream iconStream)
|
||||||
|
{
|
||||||
|
const int sizeIconDir = 6;
|
||||||
|
const int sizeIconDirEntry = 16;
|
||||||
|
IBitmapWithNativeSupport bmpPngExtracted = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var srcBuf = new byte[iconStream.Length];
|
||||||
|
iconStream.Read(srcBuf, 0, (int)iconStream.Length);
|
||||||
|
int iCount = BitConverter.ToInt16(srcBuf, 4);
|
||||||
|
for (var iIndex = 0; iIndex < iCount; iIndex++)
|
||||||
|
{
|
||||||
|
int iWidth = srcBuf[sizeIconDir + sizeIconDirEntry * iIndex];
|
||||||
|
int iHeight = srcBuf[sizeIconDir + sizeIconDirEntry * iIndex + 1];
|
||||||
|
if (iWidth != 0 || iHeight != 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
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! :)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return bmpPngExtracted;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
33
src/Greenshot.Gfx/Formats/SvgFormatReader.cs
Normal file
33
src/Greenshot.Gfx/Formats/SvgFormatReader.cs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using Dapplo.Log;
|
||||||
|
|
||||||
|
namespace Greenshot.Gfx.Formats
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This implements a IImageFormatReader which reads svg
|
||||||
|
/// </summary>
|
||||||
|
public class SvgFormatReader : IImageFormatReader
|
||||||
|
{
|
||||||
|
private static readonly LogSource Log = new LogSource();
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IEnumerable<string> SupportedFormats { get; } = new []{ "svg" };
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IBitmapWithNativeSupport Read(Stream stream, string extension = null)
|
||||||
|
{
|
||||||
|
stream.Position = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return SvgBitmap.FromStream(stream);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error().WriteLine(ex, "Can't load SVG");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
75
src/Greenshot.Gfx/GfxModule.cs
Normal file
75
src/Greenshot.Gfx/GfxModule.cs
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
// Greenshot - a free and open source screenshot tool
|
||||||
|
// Copyright (C) 2007-2019 Thomas Braun, Jens Klingen, Robin Krom
|
||||||
|
//
|
||||||
|
// For more information see: http://getgreenshot.org/
|
||||||
|
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 1 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
using Autofac;
|
||||||
|
using Dapplo.Addons;
|
||||||
|
using Greenshot.Gfx;
|
||||||
|
using Greenshot.Gfx.Formats;
|
||||||
|
|
||||||
|
namespace Greenshot.Gfx
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public class GfxModule : AddonModule
|
||||||
|
{
|
||||||
|
private void Register(IImageFormatReader reader)
|
||||||
|
{
|
||||||
|
foreach(var extension in reader.SupportedFormats)
|
||||||
|
{
|
||||||
|
BitmapHelper.StreamConverters[extension] = reader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
protected override void Load(ContainerBuilder builder)
|
||||||
|
{
|
||||||
|
builder
|
||||||
|
.RegisterType<GenericGdiFormatReader>()
|
||||||
|
.As<IImageFormatReader>()
|
||||||
|
.AsSelf()
|
||||||
|
.SingleInstance()
|
||||||
|
.AutoActivate()
|
||||||
|
.OnActivated(args =>
|
||||||
|
{
|
||||||
|
Register(args.Instance);
|
||||||
|
});
|
||||||
|
|
||||||
|
builder
|
||||||
|
.RegisterType<IcoFormatReader>()
|
||||||
|
.As<IImageFormatReader>()
|
||||||
|
.SingleInstance()
|
||||||
|
.AutoActivate()
|
||||||
|
.OnActivated(args =>
|
||||||
|
{
|
||||||
|
Register(args.Instance);
|
||||||
|
});
|
||||||
|
|
||||||
|
builder
|
||||||
|
.RegisterType<SvgFormatReader>()
|
||||||
|
.As<IImageFormatReader>()
|
||||||
|
.SingleInstance()
|
||||||
|
.AutoActivate()
|
||||||
|
.OnActivated(args =>
|
||||||
|
{
|
||||||
|
Register(args.Instance);
|
||||||
|
});
|
||||||
|
|
||||||
|
base.Load(builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue