mirror of
https://github.com/cyanfish/naps2.git
synced 2024-09-11 15:26:55 +03:00
Remove ImageContext from IMemoryImage constructors
Now that ImageContext is stateless it can be created on demand, simplifying a lot of things.
This commit is contained in:
parent
8f9cbfc14e
commit
e547d35be1
@ -12,10 +12,8 @@ namespace NAPS2.Images.Gdi;
|
|||||||
#endif
|
#endif
|
||||||
public class GdiImage : IMemoryImage
|
public class GdiImage : IMemoryImage
|
||||||
{
|
{
|
||||||
public GdiImage(ImageContext imageContext, Bitmap bitmap)
|
public GdiImage(Bitmap bitmap)
|
||||||
{
|
{
|
||||||
if (imageContext is not GdiImageContext) throw new ArgumentException("Expected GdiImageContext");
|
|
||||||
ImageContext = imageContext;
|
|
||||||
if (bitmap == null)
|
if (bitmap == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(bitmap));
|
throw new ArgumentNullException(nameof(bitmap));
|
||||||
@ -25,7 +23,7 @@ public class GdiImage : IMemoryImage
|
|||||||
OriginalFileFormat = bitmap.RawFormat.AsImageFileFormat();
|
OriginalFileFormat = bitmap.RawFormat.AsImageFileFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageContext ImageContext { get; }
|
public ImageContext ImageContext { get; } = new GdiImageContext();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the underlying System.Drawing.Bitmap object for this image.
|
/// Gets the underlying System.Drawing.Bitmap object for this image.
|
||||||
|
@ -28,7 +28,7 @@ public class GdiImageContext : ImageContext
|
|||||||
{
|
{
|
||||||
var memoryStream = EnsureMemoryStream(stream);
|
var memoryStream = EnsureMemoryStream(stream);
|
||||||
using var bitmap = new Bitmap(memoryStream);
|
using var bitmap = new Bitmap(memoryStream);
|
||||||
return new GdiImage(this, bitmap).Copy();
|
return new GdiImage(bitmap).Copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadFramesCore(Action<IMemoryImage> produceImage, Stream stream,
|
protected override void LoadFramesCore(Action<IMemoryImage> produceImage, Stream stream,
|
||||||
@ -42,7 +42,7 @@ public class GdiImageContext : ImageContext
|
|||||||
progress.Report(i, count);
|
progress.Report(i, count);
|
||||||
if (progress.IsCancellationRequested) break;
|
if (progress.IsCancellationRequested) break;
|
||||||
bitmap.SelectActiveFrame(FrameDimension.Page, i);
|
bitmap.SelectActiveFrame(FrameDimension.Page, i);
|
||||||
produceImage(new GdiImage(this, bitmap).Copy());
|
produceImage(new GdiImage(bitmap).Copy());
|
||||||
}
|
}
|
||||||
progress.Report(count, count);
|
progress.Report(count, count);
|
||||||
}
|
}
|
||||||
@ -85,6 +85,6 @@ public class GdiImageContext : ImageContext
|
|||||||
}
|
}
|
||||||
bitmap.Palette = p;
|
bitmap.Palette = p;
|
||||||
}
|
}
|
||||||
return new GdiImage(this, bitmap);
|
return new GdiImage(bitmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -53,7 +53,7 @@ public class GdiImageTransformer : AbstractImageTransformer<GdiImage>
|
|||||||
g.TranslateTransform(-image.Width / 2.0f, -image.Height / 2.0f);
|
g.TranslateTransform(-image.Width / 2.0f, -image.Height / 2.0f);
|
||||||
g.DrawImage(image.Bitmap, new Rectangle(0, 0, image.Width, image.Height));
|
g.DrawImage(image.Bitmap, new Rectangle(0, 0, image.Width, image.Height));
|
||||||
}
|
}
|
||||||
var resultImage = new GdiImage(ImageContext, result);
|
var resultImage = new GdiImage(result);
|
||||||
OptimizePixelFormat(image, ref resultImage);
|
OptimizePixelFormat(image, ref resultImage);
|
||||||
image.Dispose();
|
image.Dispose();
|
||||||
return resultImage;
|
return resultImage;
|
||||||
@ -82,6 +82,6 @@ public class GdiImageTransformer : AbstractImageTransformer<GdiImage>
|
|||||||
image.HorizontalResolution * image.Width / transform.Width,
|
image.HorizontalResolution * image.Width / transform.Width,
|
||||||
image.VerticalResolution * image.Height / transform.Height);
|
image.VerticalResolution * image.Height / transform.Height);
|
||||||
image.Dispose();
|
image.Dispose();
|
||||||
return new GdiImage(ImageContext, result);
|
return new GdiImage(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,17 +7,15 @@ namespace NAPS2.Images.Gtk;
|
|||||||
|
|
||||||
public class GtkImage : IMemoryImage
|
public class GtkImage : IMemoryImage
|
||||||
{
|
{
|
||||||
public GtkImage(ImageContext imageContext, Pixbuf pixbuf)
|
public GtkImage(Pixbuf pixbuf)
|
||||||
{
|
{
|
||||||
if (imageContext is not GtkImageContext) throw new ArgumentException("Expected GtkImageContext");
|
|
||||||
LeakTracer.StartTracking(this);
|
LeakTracer.StartTracking(this);
|
||||||
ImageContext = imageContext;
|
|
||||||
Pixbuf = pixbuf;
|
Pixbuf = pixbuf;
|
||||||
HorizontalResolution = float.TryParse(pixbuf.GetOption("x-dpi"), out var xDpi) ? xDpi : 0;
|
HorizontalResolution = float.TryParse(pixbuf.GetOption("x-dpi"), out var xDpi) ? xDpi : 0;
|
||||||
VerticalResolution = float.TryParse(pixbuf.GetOption("y-dpi"), out var yDpi) ? yDpi : 0;
|
VerticalResolution = float.TryParse(pixbuf.GetOption("y-dpi"), out var yDpi) ? yDpi : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageContext ImageContext { get; }
|
public ImageContext ImageContext { get; } = new GtkImageContext();
|
||||||
|
|
||||||
public Pixbuf Pixbuf { get; }
|
public Pixbuf Pixbuf { get; }
|
||||||
|
|
||||||
@ -142,7 +140,7 @@ public class GtkImage : IMemoryImage
|
|||||||
return (keys.ToArray(), values.ToArray());
|
return (keys.ToArray(), values.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMemoryImage Clone() => new GtkImage(ImageContext, (Pixbuf) Pixbuf.Clone())
|
public IMemoryImage Clone() => new GtkImage((Pixbuf) Pixbuf.Clone())
|
||||||
{
|
{
|
||||||
OriginalFileFormat = OriginalFileFormat,
|
OriginalFileFormat = OriginalFileFormat,
|
||||||
LogicalPixelFormat = LogicalPixelFormat,
|
LogicalPixelFormat = LogicalPixelFormat,
|
||||||
|
@ -32,7 +32,7 @@ public class GtkImageContext : ImageContext
|
|||||||
_tiffIo.LoadTiff(img => { image = img; cts.Cancel(); }, stream, cts.Token);
|
_tiffIo.LoadTiff(img => { image = img; cts.Cancel(); }, stream, cts.Token);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
return new GtkImage(this, new Pixbuf(stream));
|
return new GtkImage(new Pixbuf(stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadFramesCore(Action<IMemoryImage> produceImage, Stream stream,
|
protected override void LoadFramesCore(Action<IMemoryImage> produceImage, Stream stream,
|
||||||
@ -65,6 +65,6 @@ public class GtkImageContext : ImageContext
|
|||||||
throw new ArgumentException("Unsupported pixel format");
|
throw new ArgumentException("Unsupported pixel format");
|
||||||
}
|
}
|
||||||
var pixbuf = new Pixbuf(Colorspace.Rgb, pixelFormat == ImagePixelFormat.ARGB32, 8, width, height);
|
var pixbuf = new Pixbuf(Colorspace.Rgb, pixelFormat == ImagePixelFormat.ARGB32, 8, width, height);
|
||||||
return new GtkImage(this, pixbuf);
|
return new GtkImage(pixbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,7 +31,7 @@ public class GtkImageTransformer : AbstractImageTransformer<GtkImage>
|
|||||||
context.Translate(-image.Width / 2.0, -image.Height / 2.0);
|
context.Translate(-image.Width / 2.0, -image.Height / 2.0);
|
||||||
CairoHelper.SetSourcePixbuf(context, image.Pixbuf, 0, 0);
|
CairoHelper.SetSourcePixbuf(context, image.Pixbuf, 0, 0);
|
||||||
context.Paint();
|
context.Paint();
|
||||||
var newImage = new GtkImage(ImageContext, new Pixbuf(surface, 0, 0, width, height));
|
var newImage = new GtkImage(new Pixbuf(surface, 0, 0, width, height));
|
||||||
OptimizePixelFormat(image, ref newImage);
|
OptimizePixelFormat(image, ref newImage);
|
||||||
newImage.LogicalPixelFormat = image.LogicalPixelFormat;
|
newImage.LogicalPixelFormat = image.LogicalPixelFormat;
|
||||||
newImage.SetResolution(xres, yres);
|
newImage.SetResolution(xres, yres);
|
||||||
@ -49,7 +49,7 @@ public class GtkImageTransformer : AbstractImageTransformer<GtkImage>
|
|||||||
context.Scale(transform.Width / (double) image.Width, transform.Height / (double) image.Height);
|
context.Scale(transform.Width / (double) image.Width, transform.Height / (double) image.Height);
|
||||||
CairoHelper.SetSourcePixbuf(context, image.Pixbuf, 0, 0);
|
CairoHelper.SetSourcePixbuf(context, image.Pixbuf, 0, 0);
|
||||||
context.Paint();
|
context.Paint();
|
||||||
var newImage = new GtkImage(ImageContext, new Pixbuf(surface, 0, 0, transform.Width, transform.Height));
|
var newImage = new GtkImage(new Pixbuf(surface, 0, 0, transform.Width, transform.Height));
|
||||||
newImage.LogicalPixelFormat = image.LogicalPixelFormat == ImagePixelFormat.BW1
|
newImage.LogicalPixelFormat = image.LogicalPixelFormat == ImagePixelFormat.BW1
|
||||||
? ImagePixelFormat.Gray8
|
? ImagePixelFormat.Gray8
|
||||||
: image.LogicalPixelFormat;
|
: image.LogicalPixelFormat;
|
||||||
|
@ -15,17 +15,15 @@ namespace NAPS2.Images.ImageSharp;
|
|||||||
|
|
||||||
public class ImageSharpImage : IMemoryImage
|
public class ImageSharpImage : IMemoryImage
|
||||||
{
|
{
|
||||||
public ImageSharpImage(ImageContext imageContext, Image image)
|
public ImageSharpImage(Image image)
|
||||||
{
|
{
|
||||||
if (imageContext is not ImageSharpImageContext) throw new ArgumentException("Expected ImageSharpImageContext");
|
|
||||||
LeakTracer.StartTracking(this);
|
LeakTracer.StartTracking(this);
|
||||||
ImageContext = imageContext;
|
|
||||||
// TODO: Something similar to MacImage where if it's not a supported pixel type we convert
|
// TODO: Something similar to MacImage where if it's not a supported pixel type we convert
|
||||||
// TODO: Though we might also want to add support where reasonable, e.g. we can probably support argb or bgr pretty easily?
|
// TODO: Though we might also want to add support where reasonable, e.g. we can probably support argb or bgr pretty easily?
|
||||||
Image = image;
|
Image = image;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageContext ImageContext { get; }
|
public ImageContext ImageContext { get; } = new ImageSharpImageContext();
|
||||||
|
|
||||||
public Image Image { get; }
|
public Image Image { get; }
|
||||||
|
|
||||||
@ -156,7 +154,7 @@ public class ImageSharpImage : IMemoryImage
|
|||||||
return encoder;
|
return encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMemoryImage Clone() => new ImageSharpImage(ImageContext, Image.Clone(_ => { }))
|
public IMemoryImage Clone() => new ImageSharpImage(Image.Clone(_ => { }))
|
||||||
{
|
{
|
||||||
OriginalFileFormat = OriginalFileFormat,
|
OriginalFileFormat = OriginalFileFormat,
|
||||||
LogicalPixelFormat = LogicalPixelFormat
|
LogicalPixelFormat = LogicalPixelFormat
|
||||||
|
@ -36,7 +36,7 @@ public class ImageSharpImageContext : ImageContext
|
|||||||
|
|
||||||
protected override IMemoryImage LoadCore(Stream stream, ImageFileFormat format)
|
protected override IMemoryImage LoadCore(Stream stream, ImageFileFormat format)
|
||||||
{
|
{
|
||||||
return new ImageSharpImage(this, Image.Load(GetDecoderOptions(), stream));
|
return new ImageSharpImage(Image.Load(GetDecoderOptions(), stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadFramesCore(Action<IMemoryImage> produceImage, Stream stream,
|
protected override void LoadFramesCore(Action<IMemoryImage> produceImage, Stream stream,
|
||||||
@ -66,6 +66,6 @@ public class ImageSharpImageContext : ImageContext
|
|||||||
ImagePixelFormat.Gray8 or ImagePixelFormat.BW1 => new Image<L8>(GetConfiguration(), width, height),
|
ImagePixelFormat.Gray8 or ImagePixelFormat.BW1 => new Image<L8>(GetConfiguration(), width, height),
|
||||||
_ => throw new InvalidOperationException("Unsupported pixel format")
|
_ => throw new InvalidOperationException("Unsupported pixel format")
|
||||||
};
|
};
|
||||||
return new ImageSharpImage(this, image);
|
return new ImageSharpImage(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -33,7 +33,7 @@ public class ImageSharpImageTransformer : AbstractImageTransformer<ImageSharpIma
|
|||||||
var cropRect = new Rectangle((copy.Width - width) / 2, (copy.Height - height) / 2, width, height);
|
var cropRect = new Rectangle((copy.Width - width) / 2, (copy.Height - height) / 2, width, height);
|
||||||
copy.Mutate(x => x.Crop(cropRect));
|
copy.Mutate(x => x.Crop(cropRect));
|
||||||
|
|
||||||
var newImage = new ImageSharpImage(ImageContext, copy);
|
var newImage = new ImageSharpImage(copy);
|
||||||
// TODO: In Gdi, we convert this back to BW1. Should we do the same?
|
// TODO: In Gdi, we convert this back to BW1. Should we do the same?
|
||||||
newImage.LogicalPixelFormat = image.LogicalPixelFormat == ImagePixelFormat.BW1
|
newImage.LogicalPixelFormat = image.LogicalPixelFormat == ImagePixelFormat.BW1
|
||||||
? ImagePixelFormat.Gray8
|
? ImagePixelFormat.Gray8
|
||||||
|
@ -4,10 +4,8 @@ namespace NAPS2.Images.Mac;
|
|||||||
|
|
||||||
public class MacImage : IMemoryImage
|
public class MacImage : IMemoryImage
|
||||||
{
|
{
|
||||||
public MacImage(ImageContext imageContext, NSImage image)
|
public MacImage(NSImage image)
|
||||||
{
|
{
|
||||||
if (imageContext is not MacImageContext) throw new ArgumentException("Expected MacImageContext");
|
|
||||||
ImageContext = imageContext;
|
|
||||||
NsImage = image ?? throw new ArgumentNullException(nameof(image));
|
NsImage = image ?? throw new ArgumentNullException(nameof(image));
|
||||||
var reps = NsImage.Representations();
|
var reps = NsImage.Representations();
|
||||||
if (reps.Length != 1)
|
if (reps.Length != 1)
|
||||||
@ -69,7 +67,7 @@ public class MacImage : IMemoryImage
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageContext ImageContext { get; }
|
public ImageContext ImageContext { get; } = new MacImageContext();
|
||||||
|
|
||||||
public NSImage NsImage { get; }
|
public NSImage NsImage { get; }
|
||||||
|
|
||||||
@ -208,7 +206,7 @@ public class MacImage : IMemoryImage
|
|||||||
#else
|
#else
|
||||||
var nsImage = (NSImage) NsImage.Copy();
|
var nsImage = (NSImage) NsImage.Copy();
|
||||||
#endif
|
#endif
|
||||||
return new MacImage(ImageContext, nsImage)
|
return new MacImage(nsImage)
|
||||||
{
|
{
|
||||||
OriginalFileFormat = OriginalFileFormat,
|
OriginalFileFormat = OriginalFileFormat,
|
||||||
LogicalPixelFormat = LogicalPixelFormat
|
LogicalPixelFormat = LogicalPixelFormat
|
||||||
|
@ -37,7 +37,7 @@ public class MacImageContext : ImageContext
|
|||||||
image.Dispose();
|
image.Dispose();
|
||||||
return CreateImage(reps[0]);
|
return CreateImage(reps[0]);
|
||||||
}
|
}
|
||||||
return new MacImage(this, image);
|
return new MacImage(image);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -93,7 +93,7 @@ public class MacImageContext : ImageContext
|
|||||||
frame = new NSImage(rep.Size);
|
frame = new NSImage(rep.Size);
|
||||||
}
|
}
|
||||||
frame.AddRepresentation(rep);
|
frame.AddRepresentation(rep);
|
||||||
return new MacImage(this, frame);
|
return new MacImage(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IMemoryImage Create(int width, int height, ImagePixelFormat pixelFormat)
|
public override IMemoryImage Create(int width, int height, ImagePixelFormat pixelFormat)
|
||||||
@ -104,7 +104,7 @@ public class MacImageContext : ImageContext
|
|||||||
var image = new NSImage(rep.Size);
|
var image = new NSImage(rep.Size);
|
||||||
image.AddRepresentation(rep);
|
image.AddRepresentation(rep);
|
||||||
rep.Dispose();
|
rep.Dispose();
|
||||||
return new MacImage(this, image);
|
return new MacImage(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,18 +19,16 @@ public class WpfImage : IMemoryImage
|
|||||||
|
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
public WpfImage(ImageContext imageContext, WriteableBitmap bitmap)
|
public WpfImage(WriteableBitmap bitmap)
|
||||||
{
|
{
|
||||||
if (imageContext is not WpfImageContext) throw new ArgumentException("Expected WpfImageContext");
|
|
||||||
LeakTracer.StartTracking(this);
|
LeakTracer.StartTracking(this);
|
||||||
ImageContext = imageContext;
|
|
||||||
// TODO: Something similar to MacImage where if it's not a supported pixel type we convert
|
// TODO: Something similar to MacImage where if it's not a supported pixel type we convert
|
||||||
WpfPixelFormatFixer.MaybeFixPixelFormat(ref bitmap);
|
WpfPixelFormatFixer.MaybeFixPixelFormat(ref bitmap);
|
||||||
Bitmap = bitmap;
|
Bitmap = bitmap;
|
||||||
DetachFromDispatcher(Bitmap);
|
DetachFromDispatcher(Bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageContext ImageContext { get; }
|
public ImageContext ImageContext { get; } = new WpfImageContext();
|
||||||
|
|
||||||
public WriteableBitmap Bitmap { get; private set; }
|
public WriteableBitmap Bitmap { get; private set; }
|
||||||
|
|
||||||
@ -166,7 +164,7 @@ public class WpfImage : IMemoryImage
|
|||||||
public IMemoryImage Clone()
|
public IMemoryImage Clone()
|
||||||
{
|
{
|
||||||
if (_disposed) throw new InvalidOperationException();
|
if (_disposed) throw new InvalidOperationException();
|
||||||
return new WpfImage(ImageContext, Bitmap.Clone())
|
return new WpfImage(Bitmap.Clone())
|
||||||
{
|
{
|
||||||
OriginalFileFormat = OriginalFileFormat,
|
OriginalFileFormat = OriginalFileFormat,
|
||||||
LogicalPixelFormat = LogicalPixelFormat
|
LogicalPixelFormat = LogicalPixelFormat
|
||||||
|
@ -32,7 +32,7 @@ public class WpfImageContext : ImageContext
|
|||||||
bitmap.CacheOption = BitmapCacheOption.OnLoad;
|
bitmap.CacheOption = BitmapCacheOption.OnLoad;
|
||||||
bitmap.EndInit();
|
bitmap.EndInit();
|
||||||
bitmap.Freeze();
|
bitmap.Freeze();
|
||||||
return new WpfImage(this, new WriteableBitmap(bitmap));
|
return new WpfImage(new WriteableBitmap(bitmap));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadFramesCore(Action<IMemoryImage> produceImage, Stream stream,
|
protected override void LoadFramesCore(Action<IMemoryImage> produceImage, Stream stream,
|
||||||
@ -46,7 +46,7 @@ public class WpfImageContext : ImageContext
|
|||||||
foreach (var frame in decoder.Frames)
|
foreach (var frame in decoder.Frames)
|
||||||
{
|
{
|
||||||
if (progress.IsCancellationRequested) return;
|
if (progress.IsCancellationRequested) return;
|
||||||
produceImage(new WpfImage(this, new WriteableBitmap(frame)));
|
produceImage(new WpfImage(new WriteableBitmap(frame)));
|
||||||
progress.Report(++i, decoder.Frames.Count);
|
progress.Report(++i, decoder.Frames.Count);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -77,6 +77,6 @@ public class WpfImageContext : ImageContext
|
|||||||
_ => throw new InvalidOperationException("Unsupported pixel format")
|
_ => throw new InvalidOperationException("Unsupported pixel format")
|
||||||
};
|
};
|
||||||
var image = new WriteableBitmap(width, height, 0, 0, wpfPixelFormat, null);
|
var image = new WriteableBitmap(width, height, 0, 0, wpfPixelFormat, null);
|
||||||
return new WpfImage(this, image);
|
return new WpfImage(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -34,7 +34,7 @@ public class WpfImageTransformer : AbstractImageTransformer<WpfImage>
|
|||||||
var rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Default);
|
var rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Default);
|
||||||
rtb.Render(visual);
|
rtb.Render(visual);
|
||||||
|
|
||||||
var newImage = new WpfImage(ImageContext, new WriteableBitmap(rtb));
|
var newImage = new WpfImage(new WriteableBitmap(rtb));
|
||||||
// TODO: In Gdi, we convert this back to BW1 (or the original pixel format). Should we do the same?
|
// TODO: In Gdi, we convert this back to BW1 (or the original pixel format). Should we do the same?
|
||||||
newImage.LogicalPixelFormat = image.LogicalPixelFormat == ImagePixelFormat.BW1
|
newImage.LogicalPixelFormat = image.LogicalPixelFormat == ImagePixelFormat.BW1
|
||||||
? ImagePixelFormat.Gray8
|
? ImagePixelFormat.Gray8
|
||||||
@ -49,7 +49,7 @@ public class WpfImageTransformer : AbstractImageTransformer<WpfImage>
|
|||||||
var copy = new TransformedBitmap(image.Bitmap,
|
var copy = new TransformedBitmap(image.Bitmap,
|
||||||
new System.Windows.Media.ScaleTransform(transform.Width / (double) image.Width,
|
new System.Windows.Media.ScaleTransform(transform.Width / (double) image.Width,
|
||||||
transform.Height / (double) image.Height));
|
transform.Height / (double) image.Height));
|
||||||
var newImage = new WpfImage(ImageContext, new WriteableBitmap(copy));
|
var newImage = new WpfImage(new WriteableBitmap(copy));
|
||||||
newImage.LogicalPixelFormat = image.LogicalPixelFormat == ImagePixelFormat.BW1
|
newImage.LogicalPixelFormat = image.LogicalPixelFormat == ImagePixelFormat.BW1
|
||||||
? ImagePixelFormat.Gray8
|
? ImagePixelFormat.Gray8
|
||||||
: image.LogicalPixelFormat;
|
: image.LogicalPixelFormat;
|
||||||
|
@ -8,8 +8,6 @@ namespace NAPS2.Images;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IMemoryImage : IImageStorage
|
public interface IMemoryImage : IImageStorage
|
||||||
{
|
{
|
||||||
// TODO: Now that ImageContext objects are fully stateless, we can maybe eliminate ImageContext as a parameter
|
|
||||||
// in IMemoryImage constructors and just create the appropriate ImageContext objects automatically.
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the image context used to create this image.
|
/// Gets the image context used to create this image.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -44,9 +44,9 @@ public class GtkEtoPlatform : EtoPlatform
|
|||||||
return new Bitmap(new BitmapHandler(pixbuf));
|
return new Bitmap(new BitmapHandler(pixbuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IMemoryImage FromBitmap(ImageContext imageContext, Bitmap bitmap)
|
public override IMemoryImage FromBitmap(Bitmap bitmap)
|
||||||
{
|
{
|
||||||
return new GtkImage(imageContext, bitmap.ToGdk());
|
return new GtkImage(bitmap.ToGdk());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetClipboardImage(Clipboard clipboard, ProcessedImage processedImage, IMemoryImage memoryImage)
|
public override void SetClipboardImage(Clipboard clipboard, ProcessedImage processedImage, IMemoryImage memoryImage)
|
||||||
@ -57,7 +57,7 @@ public class GtkEtoPlatform : EtoPlatform
|
|||||||
clipboard.Image = memoryImage.ToEtoImage();
|
clipboard.Image = memoryImage.ToEtoImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IMemoryImage DrawHourglass(ImageContext imageContext, IMemoryImage image)
|
public override IMemoryImage DrawHourglass(IMemoryImage image)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
return image;
|
return image;
|
||||||
|
@ -59,12 +59,12 @@ public class MacEtoPlatform : EtoPlatform
|
|||||||
return new Bitmap(new BitmapHandler((NSImage) nsImage.Copy()));
|
return new Bitmap(new BitmapHandler((NSImage) nsImage.Copy()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IMemoryImage FromBitmap(ImageContext imageContext, Bitmap bitmap)
|
public override IMemoryImage FromBitmap(Bitmap bitmap)
|
||||||
{
|
{
|
||||||
return new MacImage(imageContext, bitmap.ToNS());
|
return new MacImage(bitmap.ToNS());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IMemoryImage DrawHourglass(ImageContext imageContext, IMemoryImage image)
|
public override IMemoryImage DrawHourglass(IMemoryImage image)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
return image;
|
return image;
|
||||||
|
@ -104,12 +104,12 @@ public class WinFormsEtoPlatform : EtoPlatform
|
|||||||
return bitmap.ToEto();
|
return bitmap.ToEto();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IMemoryImage FromBitmap(ImageContext imageContext, Bitmap bitmap)
|
public override IMemoryImage FromBitmap(Bitmap bitmap)
|
||||||
{
|
{
|
||||||
return new GdiImage(imageContext, (SD.Bitmap) bitmap.ToSD());
|
return new GdiImage((SD.Bitmap) bitmap.ToSD());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IMemoryImage DrawHourglass(ImageContext imageContext, IMemoryImage image)
|
public override IMemoryImage DrawHourglass(IMemoryImage image)
|
||||||
{
|
{
|
||||||
var bitmap = new System.Drawing.Bitmap(image.Width, image.Height);
|
var bitmap = new System.Drawing.Bitmap(image.Width, image.Height);
|
||||||
using (var g = SD.Graphics.FromImage(bitmap))
|
using (var g = SD.Graphics.FromImage(bitmap))
|
||||||
@ -131,7 +131,7 @@ public class WinFormsEtoPlatform : EtoPlatform
|
|||||||
g.DrawImage(hourglass, new SD.Rectangle((bitmap.Width - 32) / 2, (bitmap.Height - 32) / 2, 32, 32));
|
g.DrawImage(hourglass, new SD.Rectangle((bitmap.Width - 32) / 2, (bitmap.Height - 32) / 2, 32, 32));
|
||||||
}
|
}
|
||||||
image.Dispose();
|
image.Dispose();
|
||||||
return new GdiImage(imageContext, bitmap);
|
return new GdiImage(bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetFrame(Control container, Control control, Point location, Size size, bool inOverlay)
|
public override void SetFrame(Control container, Control control, Point location, Size size, bool inOverlay)
|
||||||
|
@ -17,7 +17,7 @@ public class GdiModule : Module
|
|||||||
builder.RegisterBuildCallback(ctx =>
|
builder.RegisterBuildCallback(ctx =>
|
||||||
{
|
{
|
||||||
var scanningContext = ctx.Resolve<ScanningContext>();
|
var scanningContext = ctx.Resolve<ScanningContext>();
|
||||||
scanningContext.LegacyTwainDriver = new LegacyTwainScanDriver(scanningContext);
|
scanningContext.LegacyTwainDriver = new LegacyTwainScanDriver();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,13 +5,6 @@ namespace NAPS2.Scan.Twain.Legacy;
|
|||||||
|
|
||||||
internal class LegacyTwainScanDriver : IScanDriver
|
internal class LegacyTwainScanDriver : IScanDriver
|
||||||
{
|
{
|
||||||
private readonly ScanningContext _scanningContext;
|
|
||||||
|
|
||||||
public LegacyTwainScanDriver(ScanningContext scanningContext)
|
|
||||||
{
|
|
||||||
_scanningContext = scanningContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task GetDevices(ScanOptions options, CancellationToken cancelToken, Action<ScanDevice> callback)
|
public Task GetDevices(ScanOptions options, CancellationToken cancelToken, Action<ScanDevice> callback)
|
||||||
{
|
{
|
||||||
Check32Bit();
|
Check32Bit();
|
||||||
@ -28,7 +21,7 @@ internal class LegacyTwainScanDriver : IScanDriver
|
|||||||
Action<IMemoryImage> callback)
|
Action<IMemoryImage> callback)
|
||||||
{
|
{
|
||||||
Check32Bit();
|
Check32Bit();
|
||||||
return Task.Run(() => Invoker.Current.Invoke(() => TwainApi.Scan(_scanningContext, options, callback)));
|
return Task.Run(() => Invoker.Current.Invoke(() => TwainApi.Scan(options, callback)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Check32Bit()
|
private static void Check32Bit()
|
||||||
|
@ -52,7 +52,7 @@ internal static class TwainApi
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Scan(ScanningContext scanningContext, ScanOptions options, Action<IMemoryImage> produceImage)
|
public static void Scan(ScanOptions options, Action<IMemoryImage> produceImage)
|
||||||
{
|
{
|
||||||
var tw = new Twain();
|
var tw = new Twain();
|
||||||
if (!tw.Init(options.DialogParent))
|
if (!tw.Init(options.DialogParent))
|
||||||
@ -64,7 +64,7 @@ internal static class TwainApi
|
|||||||
throw new DeviceNotFoundException();
|
throw new DeviceNotFoundException();
|
||||||
}
|
}
|
||||||
var form = new FTwainGui();
|
var form = new FTwainGui();
|
||||||
var mf = new TwainMessageFilter(scanningContext, options, tw, form);
|
var mf = new TwainMessageFilter(options, tw, form);
|
||||||
form.ShowDialog(new Win32Window(options.DialogParent));
|
form.ShowDialog(new Win32Window(options.DialogParent));
|
||||||
foreach (var b in mf.Bitmaps)
|
foreach (var b in mf.Bitmaps)
|
||||||
{
|
{
|
||||||
@ -74,7 +74,6 @@ internal static class TwainApi
|
|||||||
|
|
||||||
private class TwainMessageFilter : IMessageFilter
|
private class TwainMessageFilter : IMessageFilter
|
||||||
{
|
{
|
||||||
private readonly ScanningContext _scanningContext;
|
|
||||||
private readonly ScanOptions _settings;
|
private readonly ScanOptions _settings;
|
||||||
private readonly Twain _tw;
|
private readonly Twain _tw;
|
||||||
private readonly FTwainGui _form;
|
private readonly FTwainGui _form;
|
||||||
@ -82,9 +81,8 @@ internal static class TwainApi
|
|||||||
private bool _activated;
|
private bool _activated;
|
||||||
private bool _msgfilter;
|
private bool _msgfilter;
|
||||||
|
|
||||||
public TwainMessageFilter(ScanningContext scanningContext, ScanOptions settings, Twain tw, FTwainGui form)
|
public TwainMessageFilter(ScanOptions settings, Twain tw, FTwainGui form)
|
||||||
{
|
{
|
||||||
_scanningContext = scanningContext;
|
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
_tw = tw;
|
_tw = tw;
|
||||||
_form = form;
|
_form = form;
|
||||||
@ -129,7 +127,7 @@ internal static class TwainApi
|
|||||||
int bitcount = 0;
|
int bitcount = 0;
|
||||||
|
|
||||||
Bitmap bmp = DibUtils.BitmapFromDib(img, out bitcount);
|
Bitmap bmp = DibUtils.BitmapFromDib(img, out bitcount);
|
||||||
Bitmaps.Add(new GdiImage(_scanningContext.ImageContext, bmp));
|
Bitmaps.Add(new GdiImage(bmp));
|
||||||
}
|
}
|
||||||
_form.Close();
|
_form.Close();
|
||||||
break;
|
break;
|
||||||
|
@ -375,7 +375,7 @@ public class DesktopController
|
|||||||
var etoBitmap = (Bitmap) Clipboard.Instance.Image;
|
var etoBitmap = (Bitmap) Clipboard.Instance.Image;
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
var image = EtoPlatform.Current.FromBitmap(_scanningContext.ImageContext, etoBitmap);
|
var image = EtoPlatform.Current.FromBitmap(etoBitmap);
|
||||||
var processedImage = _scanningContext.CreateProcessedImage(image);
|
var processedImage = _scanningContext.CreateProcessedImage(image);
|
||||||
processedImage = ImportPostProcessor.AddPostProcessingData(processedImage, image,
|
processedImage = ImportPostProcessor.AddPostProcessingData(processedImage, image,
|
||||||
_thumbnailController.RenderSize, new BarcodeDetectionOptions(), true);
|
_thumbnailController.RenderSize, new BarcodeDetectionOptions(), true);
|
||||||
|
@ -23,8 +23,8 @@ public abstract class EtoPlatform
|
|||||||
public abstract IListView<T> CreateListView<T>(ListViewBehavior<T> behavior) where T : notnull;
|
public abstract IListView<T> CreateListView<T>(ListViewBehavior<T> behavior) where T : notnull;
|
||||||
public abstract void ConfigureImageButton(Button button, bool big);
|
public abstract void ConfigureImageButton(Button button, bool big);
|
||||||
public abstract Bitmap ToBitmap(IMemoryImage image);
|
public abstract Bitmap ToBitmap(IMemoryImage image);
|
||||||
public abstract IMemoryImage FromBitmap(ImageContext imageContext, Bitmap bitmap);
|
public abstract IMemoryImage FromBitmap(Bitmap bitmap);
|
||||||
public abstract IMemoryImage DrawHourglass(ImageContext imageContext, IMemoryImage thumb);
|
public abstract IMemoryImage DrawHourglass(IMemoryImage thumb);
|
||||||
public abstract void SetFrame(Control container, Control control, Point location, Size size, bool inOverlay);
|
public abstract void SetFrame(Control container, Control control, Point location, Size size, bool inOverlay);
|
||||||
public abstract Control CreateContainer();
|
public abstract Control CreateContainer();
|
||||||
public abstract void AddToContainer(Control container, Control control, bool inOverlay);
|
public abstract void AddToContainer(Control container, Control control, bool inOverlay);
|
||||||
|
@ -28,7 +28,7 @@ public class UiThumbnailProvider
|
|||||||
}
|
}
|
||||||
if (img.IsThumbnailDirty)
|
if (img.IsThumbnailDirty)
|
||||||
{
|
{
|
||||||
thumb = EtoPlatform.Current.DrawHourglass(_imageContext, thumb);
|
thumb = EtoPlatform.Current.DrawHourglass(thumb);
|
||||||
}
|
}
|
||||||
return thumb;
|
return thumb;
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ public class UiThumbnailProvider
|
|||||||
{
|
{
|
||||||
var placeholder = _imageContext.Create(thumbnailSize, thumbnailSize, ImagePixelFormat.RGB24);
|
var placeholder = _imageContext.Create(thumbnailSize, thumbnailSize, ImagePixelFormat.RGB24);
|
||||||
placeholder.Fill(_colorScheme.BackgroundColor);
|
placeholder.Fill(_colorScheme.BackgroundColor);
|
||||||
placeholder = EtoPlatform.Current.DrawHourglass(_imageContext, placeholder);
|
placeholder = EtoPlatform.Current.DrawHourglass(placeholder);
|
||||||
return placeholder;
|
return placeholder;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,7 +32,7 @@ public class GdiImageTests
|
|||||||
{
|
{
|
||||||
var bitmap = new Bitmap(new MemoryStream(ImageResources.dog_bw_invertpal));
|
var bitmap = new Bitmap(new MemoryStream(ImageResources.dog_bw_invertpal));
|
||||||
|
|
||||||
var image = new GdiImage(new GdiImageContext(), bitmap);
|
var image = new GdiImage(bitmap);
|
||||||
Assert.True(image.FixedPixelFormat);
|
Assert.True(image.FixedPixelFormat);
|
||||||
Assert.Equal(ImagePixelFormat.BW1, image.PixelFormat);
|
Assert.Equal(ImagePixelFormat.BW1, image.PixelFormat);
|
||||||
Assert.Equal(Color.Black.ToArgb(), image.Bitmap.Palette.Entries[0].ToArgb());
|
Assert.Equal(Color.Black.ToArgb(), image.Bitmap.Palette.Entries[0].ToArgb());
|
||||||
@ -49,7 +49,7 @@ public class GdiImageTests
|
|||||||
p.Entries[128] = Color.Blue;
|
p.Entries[128] = Color.Blue;
|
||||||
bitmap.Palette = p;
|
bitmap.Palette = p;
|
||||||
|
|
||||||
var image = new GdiImage(new GdiImageContext(), bitmap);
|
var image = new GdiImage(bitmap);
|
||||||
Assert.True(image.FixedPixelFormat);
|
Assert.True(image.FixedPixelFormat);
|
||||||
Assert.Equal(ImagePixelFormat.RGB24, image.PixelFormat);
|
Assert.Equal(ImagePixelFormat.RGB24, image.PixelFormat);
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ public class GdiImageTests
|
|||||||
{
|
{
|
||||||
var bitmap = new Bitmap(1, 1, PixelFormat.Format48bppRgb);
|
var bitmap = new Bitmap(1, 1, PixelFormat.Format48bppRgb);
|
||||||
|
|
||||||
var image = new GdiImage(new GdiImageContext(), bitmap);
|
var image = new GdiImage(bitmap);
|
||||||
Assert.True(image.FixedPixelFormat);
|
Assert.True(image.FixedPixelFormat);
|
||||||
Assert.Equal(ImagePixelFormat.RGB24, image.PixelFormat);
|
Assert.Equal(ImagePixelFormat.RGB24, image.PixelFormat);
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ public class GdiImageTests
|
|||||||
{
|
{
|
||||||
var bitmap = new Bitmap(1, 1, PixelFormat.Format64bppArgb);
|
var bitmap = new Bitmap(1, 1, PixelFormat.Format64bppArgb);
|
||||||
|
|
||||||
var image = new GdiImage(new GdiImageContext(), bitmap);
|
var image = new GdiImage(bitmap);
|
||||||
Assert.True(image.FixedPixelFormat);
|
Assert.True(image.FixedPixelFormat);
|
||||||
Assert.Equal(ImagePixelFormat.ARGB32, image.PixelFormat);
|
Assert.Equal(ImagePixelFormat.ARGB32, image.PixelFormat);
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ internal class DeviceOperator : ICScannerDeviceDelegate
|
|||||||
nsImage.AddRepresentation(imageRep);
|
nsImage.AddRepresentation(imageRep);
|
||||||
// TODO: Could maybe do this without the NAPS2.Images.Mac reference but that would require duplicating
|
// TODO: Could maybe do this without the NAPS2.Images.Mac reference but that would require duplicating
|
||||||
// a bunch of logic to normalize image reps etc.
|
// a bunch of logic to normalize image reps etc.
|
||||||
var macImage = new MacImage(_scanningContext.ImageContext, nsImage);
|
var macImage = new MacImage(nsImage);
|
||||||
_logger.LogDebug("Setting resolution to {Dpi}", _resolution);
|
_logger.LogDebug("Setting resolution to {Dpi}", _resolution);
|
||||||
macImage.SetResolution(_resolution, _resolution);
|
macImage.SetResolution(_resolution, _resolution);
|
||||||
if (_scanningContext.ImageContext is MacImageContext)
|
if (_scanningContext.ImageContext is MacImageContext)
|
||||||
|
Loading…
Reference in New Issue
Block a user