mirror of
https://github.com/DarthAffe/ScreenCapture.NET.git
synced 2025-12-12 13:28:35 +00:00
Merge pull request #18 from DarthAffe/FixesAndImprovememnts
Fixes and improvememnts
This commit is contained in:
commit
5eb8b5636e
@ -27,7 +27,13 @@ public static class BlackBarDetection
|
||||
return image[left, top, right - left, bottom - top];
|
||||
}
|
||||
|
||||
private static int CalculateTop(IImage image, int threshold)
|
||||
/// <summary>
|
||||
/// Calculates the first row starting from the top with at least one non black pixel.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to check.</param>
|
||||
/// <param name="threshold">The threshold of "blackness" used to detect black bars. (e. g. Threshold 5 will consider a pixel of color [5,5,5] as black.)</param>
|
||||
/// <returns>The row number of the first row with at least one non-black pixel.</returns>
|
||||
public static int CalculateTop(IImage image, int threshold)
|
||||
{
|
||||
IImage.IImageRows rows = image.Rows;
|
||||
for (int y = 0; y < rows.Count; y++)
|
||||
@ -43,7 +49,13 @@ public static class BlackBarDetection
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int CalculateBottom(IImage image, int threshold)
|
||||
/// <summary>
|
||||
/// Calculates the last row starting from the top with at least one non black pixel.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to check.</param>
|
||||
/// <param name="threshold">The threshold of "blackness" used to detect black bars. (e. g. Threshold 5 will consider a pixel of color [5,5,5] as black.)</param>
|
||||
/// <returns>The row number of the last row with at least one non-black pixel.</returns>
|
||||
public static int CalculateBottom(IImage image, int threshold)
|
||||
{
|
||||
IImage.IImageRows rows = image.Rows;
|
||||
for (int y = rows.Count - 1; y >= 0; y--)
|
||||
@ -59,7 +71,13 @@ public static class BlackBarDetection
|
||||
return rows.Count;
|
||||
}
|
||||
|
||||
private static int CalculateLeft(IImage image, int threshold)
|
||||
/// <summary>
|
||||
/// Calculates the first column starting from the left with at least one non black pixel.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to check.</param>
|
||||
/// <param name="threshold">The threshold of "blackness" used to detect black bars. (e. g. Threshold 5 will consider a pixel of color [5,5,5] as black.)</param>
|
||||
/// <returns>The column number of the first column with at least one non-black pixel.</returns>
|
||||
public static int CalculateLeft(IImage image, int threshold)
|
||||
{
|
||||
IImage.IImageColumns columns = image.Columns;
|
||||
for (int x = 0; x < columns.Count; x++)
|
||||
@ -75,7 +93,13 @@ public static class BlackBarDetection
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int CalculateRight(IImage image, int threshold)
|
||||
/// <summary>
|
||||
/// Calculates the last column starting from the top with at least one non black pixel.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to check.</param>
|
||||
/// <param name="threshold">The threshold of "blackness" used to detect black bars. (e. g. Threshold 5 will consider a pixel of color [5,5,5] as black.)</param>
|
||||
/// <returns>The column number of the last column with at least one non-black pixel.</returns>
|
||||
public static int CalculateRight(IImage image, int threshold)
|
||||
{
|
||||
IImage.IImageColumns columns = image.Columns;
|
||||
for (int x = columns.Count - 1; x >= 0; x--)
|
||||
@ -109,14 +133,20 @@ public static class BlackBarDetection
|
||||
where TColor : struct, IColor
|
||||
{
|
||||
int top = removeTop ? CalculateTop(image, threshold) : 0;
|
||||
int bottom = removeBottom ? CalculateBottom(image, threshold) : image.Height;
|
||||
int bottom = removeBottom ? CalculateBottom(image, threshold) : image.Height - 1;
|
||||
int left = removeLeft ? CalculateLeft(image, threshold) : 0;
|
||||
int right = removeRight ? CalculateRight(image, threshold) : image.Width;
|
||||
int right = removeRight ? CalculateRight(image, threshold) : image.Width - 1;
|
||||
|
||||
return image[left, top, right - left, bottom - top];
|
||||
return image[left, top, (right - left) + 1, (bottom - top) + 1];
|
||||
}
|
||||
|
||||
private static int CalculateTop<TColor>(this RefImage<TColor> image, int threshold)
|
||||
/// <summary>
|
||||
/// Calculates the first row starting from the top with at least one non black pixel.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to check.</param>
|
||||
/// <param name="threshold">The threshold of "blackness" used to detect black bars. (e. g. Threshold 5 will consider a pixel of color [5,5,5] as black.)</param>
|
||||
/// <returns>The row number of the first row with at least one non-black pixel.</returns>
|
||||
public static int CalculateTop<TColor>(this RefImage<TColor> image, int threshold)
|
||||
where TColor : struct, IColor
|
||||
{
|
||||
RefImage<TColor>.ImageRows rows = image.Rows;
|
||||
@ -133,7 +163,13 @@ public static class BlackBarDetection
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int CalculateBottom<TColor>(this RefImage<TColor> image, int threshold)
|
||||
/// <summary>
|
||||
/// Calculates the last row starting from the top with at least one non black pixel.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to check.</param>
|
||||
/// <param name="threshold">The threshold of "blackness" used to detect black bars. (e. g. Threshold 5 will consider a pixel of color [5,5,5] as black.)</param>
|
||||
/// <returns>The row number of the last row with at least one non-black pixel.</returns>
|
||||
public static int CalculateBottom<TColor>(this RefImage<TColor> image, int threshold)
|
||||
where TColor : struct, IColor
|
||||
{
|
||||
RefImage<TColor>.ImageRows rows = image.Rows;
|
||||
@ -150,7 +186,13 @@ public static class BlackBarDetection
|
||||
return rows.Count;
|
||||
}
|
||||
|
||||
private static int CalculateLeft<TColor>(this RefImage<TColor> image, int threshold)
|
||||
/// <summary>
|
||||
/// Calculates the first column starting from the left with at least one non black pixel.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to check.</param>
|
||||
/// <param name="threshold">The threshold of "blackness" used to detect black bars. (e. g. Threshold 5 will consider a pixel of color [5,5,5] as black.)</param>
|
||||
/// <returns>The column number of the first column with at least one non-black pixel.</returns>
|
||||
public static int CalculateLeft<TColor>(this RefImage<TColor> image, int threshold)
|
||||
where TColor : struct, IColor
|
||||
{
|
||||
RefImage<TColor>.ImageColumns columns = image.Columns;
|
||||
@ -167,7 +209,13 @@ public static class BlackBarDetection
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int CalculateRight<TColor>(this RefImage<TColor> image, int threshold)
|
||||
/// <summary>
|
||||
/// Calculates the last column starting from the top with at least one non black pixel.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to check.</param>
|
||||
/// <param name="threshold">The threshold of "blackness" used to detect black bars. (e. g. Threshold 5 will consider a pixel of color [5,5,5] as black.)</param>
|
||||
/// <returns>The column number of the last column with at least one non-black pixel.</returns>
|
||||
public static int CalculateRight<TColor>(this RefImage<TColor> image, int threshold)
|
||||
where TColor : struct, IColor
|
||||
{
|
||||
RefImage<TColor>.ImageColumns columns = image.Columns;
|
||||
|
||||
@ -240,7 +240,7 @@ public abstract class AbstractScreenCapture<TColor> : IScreenCapture
|
||||
_isDisposed = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Dispose" />
|
||||
/// <inheritdoc cref="IDisposable.Dispose" />
|
||||
protected virtual void Dispose(bool disposing) { }
|
||||
|
||||
#endregion
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ScreenCapture.NET;
|
||||
|
||||
@ -7,6 +8,11 @@ namespace ScreenCapture.NET;
|
||||
/// </summary>
|
||||
public interface IImage : IEnumerable<IColor>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the color format used in this image.
|
||||
/// </summary>
|
||||
ColorFormat ColorFormat { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the width of this image.
|
||||
/// </summary>
|
||||
@ -17,6 +23,11 @@ public interface IImage : IEnumerable<IColor>
|
||||
/// </summary>
|
||||
int Height { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size in bytes of this image.
|
||||
/// </summary>
|
||||
int SizeInBytes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color at the specified location.
|
||||
/// </summary>
|
||||
@ -45,6 +56,28 @@ public interface IImage : IEnumerable<IColor>
|
||||
/// </summary>
|
||||
IImageColumns Columns { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="RefImage{TColor}"/> representing this <see cref="IImage"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TColor">The color-type of the iamge.</typeparam>
|
||||
/// <returns>The <inheritdoc cref="RefImage{TColor}"/>.</returns>
|
||||
RefImage<TColor> AsRefImage<TColor>() where TColor : struct, IColor;
|
||||
|
||||
/// <summary>
|
||||
/// Copies the contents of this <see cref="IImage"/> into a destination <see cref="Span{T}"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="destination">The destination <see cref="Span{T}"/> instance.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown when <paramref name="destination"/> is shorter than the source <see cref="IImage"/> instance.
|
||||
/// </exception>
|
||||
void CopyTo(in Span<byte> destination);
|
||||
|
||||
/// <summary>
|
||||
/// Allocates a new array and copies this <see cref="IImage"/> into it.
|
||||
/// </summary>
|
||||
/// <returns>The new array containing the data of this <see cref="IImage"/>.</returns>
|
||||
byte[] ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Represents a list of rows of an image.
|
||||
/// </summary>
|
||||
@ -91,12 +124,32 @@ public interface IImage : IEnumerable<IColor>
|
||||
/// </summary>
|
||||
int Length { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size in bytes of this row.
|
||||
/// </summary>
|
||||
int SizeInBytes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IColor"/> at the specified location.
|
||||
/// </summary>
|
||||
/// <param name="x">The location to get the color from.</param>
|
||||
/// <returns>The <see cref="IColor"/> at the specified location.</returns>
|
||||
IColor this[int x] { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Copies the contents of this <see cref="IImageRow"/> into a destination <see cref="Span{T}"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="destination">The destination <see cref="Span{T}"/> instance.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown when <paramref name="destination"/> is shorter than the source <see cref="IImageRow"/> instance.
|
||||
/// </exception>
|
||||
void CopyTo(in Span<byte> destination);
|
||||
|
||||
/// <summary>
|
||||
/// Allocates a new array and copies this <see cref="IImageRow"/> into it.
|
||||
/// </summary>
|
||||
/// <returns>The new array containing the data of this <see cref="IImageRow"/>.</returns>
|
||||
byte[] ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -109,11 +162,31 @@ public interface IImage : IEnumerable<IColor>
|
||||
/// </summary>
|
||||
int Length { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size in bytes of this column.
|
||||
/// </summary>
|
||||
int SizeInBytes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IColor"/> at the specified location.
|
||||
/// </summary>
|
||||
/// <param name="y">The location to get the color from.</param>
|
||||
/// <returns>The <see cref="IColor"/> at the specified location.</returns>
|
||||
IColor this[int y] { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Copies the contents of this <see cref="IImageColumn"/> into a destination <see cref="Span{T}"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="destination">The destination <see cref="Span{T}"/> instance.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown when <paramref name="destination"/> is shorter than the source <see cref="IImageColumn"/> instance.
|
||||
/// </exception>
|
||||
void CopyTo(in Span<byte> destination);
|
||||
|
||||
/// <summary>
|
||||
/// Allocates a new array and copies this <see cref="IImageColumn"/> into it.
|
||||
/// </summary>
|
||||
/// <returns>The new array containing the data of this <see cref="IImageColumn"/>.</returns>
|
||||
byte[] ToArray();
|
||||
}
|
||||
}
|
||||
@ -18,12 +18,18 @@ public sealed class Image<TColor> : IImage
|
||||
private readonly int _y;
|
||||
private readonly int _stride;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorFormat ColorFormat => TColor.ColorFormat;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int Width { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public int Height { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public int SizeInBytes => Width * Height * TColor.ColorFormat.BytesPerPixel;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Indexer
|
||||
@ -84,6 +90,39 @@ public sealed class Image<TColor> : IImage
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
public void CopyTo(in Span<byte> destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException(nameof(destination));
|
||||
if (destination.Length < SizeInBytes) throw new ArgumentException("The destination is too small to fit this image.", nameof(destination));
|
||||
|
||||
int targetStride = Width * TColor.ColorFormat.BytesPerPixel;
|
||||
IImage.IImageRows rows = Rows;
|
||||
Span<byte> target = destination;
|
||||
foreach (IImage.IImageRow row in rows)
|
||||
{
|
||||
row.CopyTo(target);
|
||||
target = target[targetStride..];
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public byte[] ToArray()
|
||||
{
|
||||
byte[] array = new byte[SizeInBytes];
|
||||
CopyTo(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RefImage<T> AsRefImage<T>()
|
||||
where T : struct, IColor
|
||||
{
|
||||
if (typeof(T) != typeof(TColor)) throw new ArgumentException("The requested color format does not fit this image.", nameof(T));
|
||||
|
||||
return new RefImage<T>(MemoryMarshal.Cast<byte, T>(_buffer), _x, _y, Width, Height, _stride);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerator<IColor> GetEnumerator()
|
||||
{
|
||||
@ -172,6 +211,9 @@ public sealed class Image<TColor> : IImage
|
||||
/// <inheritdoc />
|
||||
public int Length => _length;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int SizeInBytes => Length * TColor.ColorFormat.BytesPerPixel;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Indexer
|
||||
@ -203,6 +245,23 @@ public sealed class Image<TColor> : IImage
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
public void CopyTo(in Span<byte> destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException(nameof(destination));
|
||||
if (destination.Length < SizeInBytes) throw new ArgumentException("The destination is too small to fit this image.", nameof(destination));
|
||||
|
||||
_buffer.AsSpan(_start, SizeInBytes).CopyTo(destination);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public byte[] ToArray()
|
||||
{
|
||||
byte[] array = new byte[SizeInBytes];
|
||||
CopyTo(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerator<IColor> GetEnumerator()
|
||||
{
|
||||
@ -290,6 +349,9 @@ public sealed class Image<TColor> : IImage
|
||||
/// <inheritdoc />
|
||||
public int Length => _length;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int SizeInBytes => Length * TColor.ColorFormat.BytesPerPixel;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Indexer
|
||||
@ -301,8 +363,8 @@ public sealed class Image<TColor> : IImage
|
||||
{
|
||||
if ((y < 0) || (y >= _length)) throw new IndexOutOfRangeException();
|
||||
|
||||
ReadOnlySpan<TColor> row = MemoryMarshal.Cast<byte, TColor>(_buffer)[_start..];
|
||||
return row[y * _step];
|
||||
ReadOnlySpan<TColor> data = MemoryMarshal.Cast<byte, TColor>(_buffer)[_start..];
|
||||
return data[y * _step];
|
||||
}
|
||||
}
|
||||
|
||||
@ -322,6 +384,31 @@ public sealed class Image<TColor> : IImage
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
public void CopyTo(in Span<byte> destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException(nameof(destination));
|
||||
if (destination.Length < SizeInBytes) throw new ArgumentException("The destination is too small to fit this image.", nameof(destination));
|
||||
|
||||
if (_step == 1)
|
||||
_buffer.AsSpan(_start, SizeInBytes).CopyTo(destination);
|
||||
else
|
||||
{
|
||||
ReadOnlySpan<TColor> data = MemoryMarshal.Cast<byte, TColor>(_buffer)[_start..];
|
||||
Span<TColor> target = MemoryMarshal.Cast<byte, TColor>(destination);
|
||||
for (int i = 0; i < Length; i++)
|
||||
target[i] = data[i * _step];
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public byte[] ToArray()
|
||||
{
|
||||
byte[] array = new byte[SizeInBytes];
|
||||
CopyTo(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerator<IColor> GetEnumerator()
|
||||
{
|
||||
|
||||
@ -13,23 +13,37 @@ public readonly ref struct RefImage<TColor>
|
||||
|
||||
private readonly int _x;
|
||||
private readonly int _y;
|
||||
private readonly int _stride;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the width of the image.
|
||||
/// </summary>
|
||||
public int Width { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the height of the image.
|
||||
/// </summary>
|
||||
public int Height { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stride (entries per row) of the underlying buffer.
|
||||
/// Only useful if you want to work with a pinned buffer.
|
||||
/// </summary>
|
||||
public int RawStride { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Indexer
|
||||
|
||||
public TColor this[int x, int y]
|
||||
public ref readonly TColor this[int x, int y]
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
if ((x < 0) || (y < 0) || (x >= Width) || (y >= Height)) throw new IndexOutOfRangeException();
|
||||
|
||||
return _pixels[((_y + y) * _stride) + (_x + x)];
|
||||
ref TColor r0 = ref MemoryMarshal.GetReference(_pixels);
|
||||
nint offset = (nint)(uint)((_y + y) * RawStride) + (_x + x);
|
||||
return ref Unsafe.Add(ref r0, offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,19 +54,19 @@ public readonly ref struct RefImage<TColor>
|
||||
{
|
||||
if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0) || ((x + width) > Width) || ((y + height) > Height)) throw new IndexOutOfRangeException();
|
||||
|
||||
return new RefImage<TColor>(_pixels, _x + x, _y + y, width, height, _stride);
|
||||
return new RefImage<TColor>(_pixels, _x + x, _y + y, width, height, RawStride);
|
||||
}
|
||||
}
|
||||
|
||||
public ImageRows Rows
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => new(_pixels, _x, _y, Width, Height, _stride);
|
||||
get => new(_pixels, _x, _y, Width, Height, RawStride);
|
||||
}
|
||||
public ImageColumns Columns
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => new(_pixels, _x, _y, Width, Height, _stride);
|
||||
get => new(_pixels, _x, _y, Width, Height, RawStride);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -66,20 +80,27 @@ public readonly ref struct RefImage<TColor>
|
||||
this._y = y;
|
||||
this.Width = width;
|
||||
this.Height = height;
|
||||
this._stride = stride;
|
||||
this.RawStride = stride;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public void CopyTo(in Span<TColor> dest)
|
||||
/// <summary>
|
||||
/// Copies the contents of this <see cref="RefImage{TColor}"/> into a destination <see cref="Span{T}"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="destination">The destination <see cref="Span{T}"/> instance.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown when <paramref name="destination"/> is shorter than the source <see cref="RefImage{TColor}"/> instance.
|
||||
/// </exception>
|
||||
public void CopyTo(in Span<TColor> destination)
|
||||
{
|
||||
if (dest == null) throw new ArgumentNullException(nameof(dest));
|
||||
if (dest.Length < (Width * Height)) throw new ArgumentException("The destination is too small to fit this image.", nameof(dest));
|
||||
if (destination == null) throw new ArgumentNullException(nameof(destination));
|
||||
if (destination.Length < (Width * Height)) throw new ArgumentException("The destination is too small to fit this image.", nameof(destination));
|
||||
|
||||
ImageRows rows = Rows;
|
||||
Span<TColor> target = dest;
|
||||
Span<TColor> target = destination;
|
||||
foreach (ReadOnlyRefEnumerable<TColor> row in rows)
|
||||
{
|
||||
row.CopyTo(target);
|
||||
@ -87,6 +108,10 @@ public readonly ref struct RefImage<TColor>
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allocates a new array and copies this <see cref="RefImage{TColor}"/> into it.
|
||||
/// </summary>
|
||||
/// <returns>The new array containing the data of this <see cref="RefImage{TColor}"/>.</returns>
|
||||
public TColor[] ToArray()
|
||||
{
|
||||
TColor[] array = new TColor[Width * Height];
|
||||
@ -94,6 +119,18 @@ public readonly ref struct RefImage<TColor>
|
||||
return array;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a reference to the first element of this image inside the full image buffer.
|
||||
/// </summary>
|
||||
public ref readonly TColor GetPinnableReference()
|
||||
{
|
||||
if (_pixels.Length == 0)
|
||||
return ref Unsafe.NullRef<TColor>();
|
||||
|
||||
int offset = (_y * RawStride) + _x;
|
||||
return ref MemoryMarshal.GetReference(_pixels[offset..]);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="System.Collections.IEnumerable.GetEnumerator"/>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ImageEnumerator GetEnumerator() => new(_pixels);
|
||||
|
||||
@ -29,9 +29,9 @@
|
||||
Reworked most of the data handling and splitted capture-logic into separate packages.
|
||||
</PackageReleaseNotes>
|
||||
|
||||
<Version>2.0.0</Version>
|
||||
<AssemblyVersion>2.0.0</AssemblyVersion>
|
||||
<FileVersion>2.0.0</FileVersion>
|
||||
<Version>2.0.1</Version>
|
||||
<AssemblyVersion>2.0.1</AssemblyVersion>
|
||||
<FileVersion>2.0.1</FileVersion>
|
||||
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
||||
@ -161,5 +161,19 @@ public class ImageTest
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestAsRefImage()
|
||||
{
|
||||
IImage image = _captureZone!.Image;
|
||||
image = image[163, 280, 720, 13];
|
||||
image = image[15, 2, 47, 8];
|
||||
|
||||
RefImage<ColorARGB> refImage = image.AsRefImage<ColorARGB>();
|
||||
|
||||
for (int y = 0; y < image.Height; y++)
|
||||
for (int x = 0; x < image.Width; x++)
|
||||
Assert.AreEqual(image[x, y], refImage[x, y]);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user