Browse Source

Merge pull request #9106 from llfab/feature/add-quality-value-to-IBitmapImpl-Save

Added new optional parameter "quality" for IBitmap and IBitmapImpl.Save method
pull/9345/head
Max Katz 4 years ago
committed by GitHub
parent
commit
4ad6f1a9b2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      src/Avalonia.Base/Media/Imaging/Bitmap.cs
  2. 14
      src/Avalonia.Base/Media/Imaging/IBitmap.cs
  3. 14
      src/Avalonia.Base/Platform/IBitmapImpl.cs
  4. 4
      src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
  5. 4
      src/Skia/Avalonia.Skia/Gpu/OpenGl/OpenGlBitmapImpl.cs
  6. 33
      src/Skia/Avalonia.Skia/Helpers/ImageSavingHelper.cs
  7. 4
      src/Skia/Avalonia.Skia/ImmutableBitmap.cs
  8. 8
      src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs
  9. 8
      src/Skia/Avalonia.Skia/WriteableBitmapImpl.cs
  10. 6
      src/Windows/Avalonia.Direct2D1/Media/Imaging/BitmapImpl.cs
  11. 2
      src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DBitmapImpl.cs
  12. 2
      src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs
  13. 2
      src/Windows/Avalonia.Direct2D1/Media/Imaging/WicBitmapImpl.cs

18
src/Avalonia.Base/Media/Imaging/Bitmap.cs

@ -121,18 +121,28 @@ namespace Avalonia.Media.Imaging
/// Saves the bitmap to a file. /// Saves the bitmap to a file.
/// </summary> /// </summary>
/// <param name="fileName">The filename.</param> /// <param name="fileName">The filename.</param>
public void Save(string fileName) /// <param name="quality">
/// The optional quality for compression.
/// The quality value is interpreted from 0 - 100. If quality is null the default quality
/// setting is applied.
/// </param>
public void Save(string fileName, int? quality = null)
{ {
PlatformImpl.Item.Save(fileName); PlatformImpl.Item.Save(fileName, quality);
} }
/// <summary> /// <summary>
/// Saves the bitmap to a stream. /// Saves the bitmap to a stream.
/// </summary> /// </summary>
/// <param name="stream">The stream.</param> /// <param name="stream">The stream.</param>
public void Save(Stream stream) /// <param name="quality">
/// The optional quality for compression.
/// The quality value is interpreted from 0 - 100. If quality is null the default quality
/// setting is applied.
/// </param>
public void Save(Stream stream, int? quality = null)
{ {
PlatformImpl.Item.Save(stream); PlatformImpl.Item.Save(stream, quality);
} }
/// <inheritdoc/> /// <inheritdoc/>

14
src/Avalonia.Base/Media/Imaging/IBitmap.cs

@ -35,12 +35,22 @@ namespace Avalonia.Media.Imaging
/// Saves the bitmap to a file. /// Saves the bitmap to a file.
/// </summary> /// </summary>
/// <param name="fileName">The filename.</param> /// <param name="fileName">The filename.</param>
void Save(string fileName); /// <param name="quality">
/// The optional quality for compression if supported by the specific backend.
/// The quality value is interpreted from 0 - 100. If quality is null the default quality
/// setting of the backend is applied.
/// </param>
void Save(string fileName, int? quality = null);
/// <summary> /// <summary>
/// Saves the bitmap to a stream in png format. /// Saves the bitmap to a stream in png format.
/// </summary> /// </summary>
/// <param name="stream">The stream.</param> /// <param name="stream">The stream.</param>
void Save(Stream stream); /// <param name="quality">
/// The optional quality for compression if supported by the specific backend.
/// The quality value is interpreted from 0 - 100. If quality is null the default quality
/// setting of the backend is applied.
/// </param>
void Save(Stream stream, int? quality = null);
} }
} }

14
src/Avalonia.Base/Platform/IBitmapImpl.cs

@ -29,12 +29,22 @@ namespace Avalonia.Platform
/// Saves the bitmap to a file. /// Saves the bitmap to a file.
/// </summary> /// </summary>
/// <param name="fileName">The filename.</param> /// <param name="fileName">The filename.</param>
void Save(string fileName); /// <param name="quality">
/// The optional quality for compression if supported by the specific backend.
/// The quality value is interpreted from 0 - 100. If quality is null the default quality
/// setting of the backend is applied.
/// </param>
void Save(string fileName, int? quality = null);
/// <summary> /// <summary>
/// Saves the bitmap to a stream in png format. /// Saves the bitmap to a stream in png format.
/// </summary> /// </summary>
/// <param name="stream">The stream.</param> /// <param name="stream">The stream.</param>
void Save(Stream stream); /// <param name="quality">
/// The optional quality for compression if supported by the specific backend.
/// The quality value is interpreted from 0 - 100. If quality is null the default quality
/// setting of the backend is applied.
/// </param>
void Save(Stream stream, int? quality = null);
} }
} }

4
src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs

@ -323,12 +323,12 @@ namespace Avalonia.Headless
public Vector Dpi { get; } public Vector Dpi { get; }
public PixelSize PixelSize { get; } public PixelSize PixelSize { get; }
public int Version { get; set; } public int Version { get; set; }
public void Save(string fileName) public void Save(string fileName, int? quality = null)
{ {
} }
public void Save(Stream stream) public void Save(Stream stream, int? quality = null)
{ {
} }

4
src/Skia/Avalonia.Skia/Gpu/OpenGl/OpenGlBitmapImpl.cs

@ -25,9 +25,9 @@ namespace Avalonia.Skia
public Vector Dpi { get; } public Vector Dpi { get; }
public PixelSize PixelSize { get; } public PixelSize PixelSize { get; }
public int Version { get; private set; } public int Version { get; private set; }
public void Save(string fileName) => throw new NotSupportedException(); public void Save(string fileName, int? quality = null) => throw new NotSupportedException();
public void Save(Stream stream) => throw new NotSupportedException(); public void Save(Stream stream, int? quality = null) => throw new NotSupportedException();
public void Draw(DrawingContextImpl context, SKRect sourceRect, SKRect destRect, SKPaint paint) public void Draw(DrawingContextImpl context, SKRect sourceRect, SKRect destRect, SKPaint paint)
{ {

33
src/Skia/Avalonia.Skia/Helpers/ImageSavingHelper.cs

@ -14,14 +14,19 @@ namespace Avalonia.Skia.Helpers
/// </summary> /// </summary>
/// <param name="image">Image to save</param> /// <param name="image">Image to save</param>
/// <param name="fileName">Target file.</param> /// <param name="fileName">Target file.</param>
public static void SaveImage(SKImage image, string fileName) /// <param name="quality">
/// The optional quality for PNG compression.
/// The quality value is interpreted from 0 - 100. If quality is null
/// the encoder applies the default quality value.
/// </param>
public static void SaveImage(SKImage image, string fileName, int? quality = null)
{ {
if (image == null) throw new ArgumentNullException(nameof(image)); if (image == null) throw new ArgumentNullException(nameof(image));
if (fileName == null) throw new ArgumentNullException(nameof(fileName)); if (fileName == null) throw new ArgumentNullException(nameof(fileName));
using (var stream = File.Create(fileName)) using (var stream = File.Create(fileName))
{ {
SaveImage(image, stream); SaveImage(image, stream, quality);
} }
} }
@ -29,16 +34,30 @@ namespace Avalonia.Skia.Helpers
/// Save Skia image to a stream. /// Save Skia image to a stream.
/// </summary> /// </summary>
/// <param name="image">Image to save</param> /// <param name="image">Image to save</param>
/// <param name="stream">Target stream.</param> /// <param name="quality">
public static void SaveImage(SKImage image, Stream stream) /// The optional quality for PNG compression.
/// The quality value is interpreted from 0 - 100. If quality is null
/// the encoder applies the default quality value.
/// </param>
public static void SaveImage(SKImage image, Stream stream, int? quality = null)
{ {
if (image == null) throw new ArgumentNullException(nameof(image)); if (image == null) throw new ArgumentNullException(nameof(image));
if (stream == null) throw new ArgumentNullException(nameof(stream)); if (stream == null) throw new ArgumentNullException(nameof(stream));
using (var data = image.Encode()) if (quality == null)
{ {
data.SaveTo(stream); using (var data = image.Encode())
{
data.SaveTo(stream);
}
}
else
{
using (var data = image.Encode(SKEncodedImageFormat.Png, (int)quality))
{
data.SaveTo(stream);
}
} }
} }
} }
} }

4
src/Skia/Avalonia.Skia/ImmutableBitmap.cs

@ -139,13 +139,13 @@ namespace Avalonia.Skia
} }
/// <inheritdoc /> /// <inheritdoc />
public void Save(string fileName) public void Save(string fileName, int? quality = null)
{ {
ImageSavingHelper.SaveImage(_image, fileName); ImageSavingHelper.SaveImage(_image, fileName);
} }
/// <inheritdoc /> /// <inheritdoc />
public void Save(Stream stream) public void Save(Stream stream, int? quality = null)
{ {
ImageSavingHelper.SaveImage(_image, stream); ImageSavingHelper.SaveImage(_image, stream);
} }

8
src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs

@ -116,20 +116,20 @@ namespace Avalonia.Skia
public int Version { get; private set; } = 1; public int Version { get; private set; } = 1;
/// <inheritdoc /> /// <inheritdoc />
public void Save(string fileName) public void Save(string fileName, int? quality = null)
{ {
using (var image = SnapshotImage()) using (var image = SnapshotImage())
{ {
ImageSavingHelper.SaveImage(image, fileName); ImageSavingHelper.SaveImage(image, fileName, quality);
} }
} }
/// <inheritdoc /> /// <inheritdoc />
public void Save(Stream stream) public void Save(Stream stream, int? quality = null)
{ {
using (var image = SnapshotImage()) using (var image = SnapshotImage())
{ {
ImageSavingHelper.SaveImage(image, stream); ImageSavingHelper.SaveImage(image, stream, quality);
} }
} }

8
src/Skia/Avalonia.Skia/WriteableBitmapImpl.cs

@ -137,20 +137,20 @@ namespace Avalonia.Skia
} }
/// <inheritdoc /> /// <inheritdoc />
public void Save(Stream stream) public void Save(Stream stream, int? quality = null)
{ {
using (var image = GetSnapshot()) using (var image = GetSnapshot())
{ {
ImageSavingHelper.SaveImage(image, stream); ImageSavingHelper.SaveImage(image, stream, quality);
} }
} }
/// <inheritdoc /> /// <inheritdoc />
public void Save(string fileName) public void Save(string fileName, int? quality = null)
{ {
using (var image = GetSnapshot()) using (var image = GetSnapshot())
{ {
ImageSavingHelper.SaveImage(image, fileName); ImageSavingHelper.SaveImage(image, fileName, quality);
} }
} }

6
src/Windows/Avalonia.Direct2D1/Media/Imaging/BitmapImpl.cs

@ -15,7 +15,7 @@ namespace Avalonia.Direct2D1.Media
public abstract OptionalDispose<D2DBitmap> GetDirect2DBitmap(SharpDX.Direct2D1.RenderTarget target); public abstract OptionalDispose<D2DBitmap> GetDirect2DBitmap(SharpDX.Direct2D1.RenderTarget target);
public void Save(string fileName) public void Save(string fileName, int? quality = null)
{ {
if (Path.GetExtension(fileName) != ".png") if (Path.GetExtension(fileName) != ".png")
{ {
@ -25,11 +25,11 @@ namespace Avalonia.Direct2D1.Media
using (FileStream s = new FileStream(fileName, FileMode.Create)) using (FileStream s = new FileStream(fileName, FileMode.Create))
{ {
Save(s); Save(s, quality);
} }
} }
public abstract void Save(Stream stream); public abstract void Save(Stream stream, int? quality = null);
public virtual void Dispose() public virtual void Dispose()
{ {

2
src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DBitmapImpl.cs

@ -43,7 +43,7 @@ namespace Avalonia.Direct2D1.Media
return new OptionalDispose<Bitmap>(_direct2DBitmap, false); return new OptionalDispose<Bitmap>(_direct2DBitmap, false);
} }
public override void Save(Stream stream) public override void Save(Stream stream, int? quality = null)
{ {
using (var encoder = new PngBitmapEncoder(Direct2D1Platform.ImagingFactory, stream)) using (var encoder = new PngBitmapEncoder(Direct2D1Platform.ImagingFactory, stream))
using (var frame = new BitmapFrameEncode(encoder)) using (var frame = new BitmapFrameEncode(encoder))

2
src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs

@ -56,7 +56,7 @@ namespace Avalonia.Direct2D1.Media.Imaging
return new OptionalDispose<D2DBitmap>(_renderTarget.Bitmap, false); return new OptionalDispose<D2DBitmap>(_renderTarget.Bitmap, false);
} }
public override void Save(Stream stream) public override void Save(Stream stream, int? quality = null)
{ {
using (var wic = new WicRenderTargetBitmapImpl(PixelSize, Dpi)) using (var wic = new WicRenderTargetBitmapImpl(PixelSize, Dpi))
{ {

2
src/Windows/Avalonia.Direct2D1/Media/Imaging/WicBitmapImpl.cs

@ -186,7 +186,7 @@ namespace Avalonia.Direct2D1.Media
return new OptionalDispose<D2DBitmap>(D2DBitmap.FromWicBitmap(renderTarget, converter), true); return new OptionalDispose<D2DBitmap>(D2DBitmap.FromWicBitmap(renderTarget, converter), true);
} }
public override void Save(Stream stream) public override void Save(Stream stream, int? quality = null)
{ {
using (var encoder = new PngBitmapEncoder(Direct2D1Platform.ImagingFactory, stream)) using (var encoder = new PngBitmapEncoder(Direct2D1Platform.ImagingFactory, stream))
using (var frame = new BitmapFrameEncode(encoder)) using (var frame = new BitmapFrameEncode(encoder))

Loading…
Cancel
Save