如何在 UWP C# 中裁剪 SoftwareBitmap
How to crop SoftwareBitmap in UWP C#
我使用 MediaCapture 对象拍摄了一张照片并获得了一个 SoftwareBitmap。
现在我想裁剪图像。
我该怎么做?
编辑-这是我到目前为止尝试过的:
public async Task<SoftwareBitmap> CorpSoftwareBitmap(SoftwareBitmap original ,float scale)
{
int startIndex = 54;
int M = original.PixelWidth;
int N = original.PixelHeight;
int m = (int)Math.Round(M * scale);
int n = (int)Math.Round(N * scale);
byte[] arrayOriginal;
using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId,ms);
encoder.SetSoftwareBitmap(original);
await encoder.FlushAsync();
arrayOriginal = new byte[ms.Size];
await ms.ReadAsync(arrayOriginal.AsBuffer(), (uint)ms.Size, InputStreamOptions.None);
}
byte[] arrayCropped;
SoftwareBitmap cropped = new SoftwareBitmap(original.BitmapPixelFormat, m, n);
using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, ms);
encoder.SetSoftwareBitmap(cropped);
await encoder.FlushAsync();
arrayCropped = new byte[ms.Size];
await ms.ReadAsync(arrayCropped.AsBuffer(), (uint)ms.Size, InputStreamOptions.None);
}
int tmp = startIndex + 2 * (N - n) * M + 2 * (M - m);
for (int i=0; i<n;i++)
{
Array.ConstrainedCopy(arrayOriginal, tmp + 4 * M * i, arrayCropped,startIndex + m * i, m);
}
cropped.CopyFromBuffer(arrayCropped.AsBuffer());
//using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
//{
// ms.GetInputStreamAt(0);
// BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, ms);
// encoder.SetSoftwareBitmap(cropped);
// await encoder.FlushAsync();
// await ms.WriteAsync(arrayCropped.AsBuffer());
//}
return cropped;
}
并且它不会将 arrayCropped 写入 cropped。这两种方法都不行,我该如何解决?
谢谢,
摩尔
有一些现有的扩展控件可以做到这一点。
例如:An ImageCropper control for the Universal Windows Platform
源代码:https://github.com/XamlBrewer/UWP-ImageCropper-/tree/master/XamlBrewer.Uwp.Controls
好的,这个有效:
public async Task<SoftwareBitmap> CorpSoftwareBitmap(SoftwareBitmap original, float scale=0.5f)
{
int startIndex = 54;//Bitmap header length
int M = original.PixelWidth;
int N = original.PixelHeight;
int m = (int)Math.Round(M * scale);
int n = (int)Math.Round(N * scale);
byte[] arrayOriginal;
using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, ms);
encoder.SetSoftwareBitmap(original);
await encoder.FlushAsync();
arrayOriginal = new byte[ms.Size];
await ms.ReadAsync(arrayOriginal.AsBuffer(), (uint)ms.Size, InputStreamOptions.None);
}
byte[] arrayCropped;
SoftwareBitmap cropped = new SoftwareBitmap(original.BitmapPixelFormat, m, n);
using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, ms);
encoder.SetSoftwareBitmap(cropped);
await encoder.FlushAsync();
arrayCropped = new byte[ms.Size];
await ms.ReadAsync(arrayCropped.AsBuffer(), (uint)ms.Size, InputStreamOptions.None);
}
int tmp = startIndex + 2 * (N - n) * M + 2 * (M - m);
for (int i = 0; i < n; i++)
Array.ConstrainedCopy(arrayOriginal, tmp + 4 * M * i, arrayCropped,4 * m * (n-1-i), 4 * m);
cropped.Dispose();
cropped = SoftwareBitmap.CreateCopyFromBuffer(arrayCropped.AsBuffer(), BitmapPixelFormat.Bgra8, m, n);
return cropped;
}
我使用 MediaCapture 对象拍摄了一张照片并获得了一个 SoftwareBitmap。 现在我想裁剪图像。 我该怎么做?
编辑-这是我到目前为止尝试过的:
public async Task<SoftwareBitmap> CorpSoftwareBitmap(SoftwareBitmap original ,float scale)
{
int startIndex = 54;
int M = original.PixelWidth;
int N = original.PixelHeight;
int m = (int)Math.Round(M * scale);
int n = (int)Math.Round(N * scale);
byte[] arrayOriginal;
using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId,ms);
encoder.SetSoftwareBitmap(original);
await encoder.FlushAsync();
arrayOriginal = new byte[ms.Size];
await ms.ReadAsync(arrayOriginal.AsBuffer(), (uint)ms.Size, InputStreamOptions.None);
}
byte[] arrayCropped;
SoftwareBitmap cropped = new SoftwareBitmap(original.BitmapPixelFormat, m, n);
using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, ms);
encoder.SetSoftwareBitmap(cropped);
await encoder.FlushAsync();
arrayCropped = new byte[ms.Size];
await ms.ReadAsync(arrayCropped.AsBuffer(), (uint)ms.Size, InputStreamOptions.None);
}
int tmp = startIndex + 2 * (N - n) * M + 2 * (M - m);
for (int i=0; i<n;i++)
{
Array.ConstrainedCopy(arrayOriginal, tmp + 4 * M * i, arrayCropped,startIndex + m * i, m);
}
cropped.CopyFromBuffer(arrayCropped.AsBuffer());
//using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
//{
// ms.GetInputStreamAt(0);
// BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, ms);
// encoder.SetSoftwareBitmap(cropped);
// await encoder.FlushAsync();
// await ms.WriteAsync(arrayCropped.AsBuffer());
//}
return cropped;
}
并且它不会将 arrayCropped 写入 cropped。这两种方法都不行,我该如何解决?
谢谢, 摩尔
有一些现有的扩展控件可以做到这一点。
例如:An ImageCropper control for the Universal Windows Platform
源代码:https://github.com/XamlBrewer/UWP-ImageCropper-/tree/master/XamlBrewer.Uwp.Controls
好的,这个有效:
public async Task<SoftwareBitmap> CorpSoftwareBitmap(SoftwareBitmap original, float scale=0.5f)
{
int startIndex = 54;//Bitmap header length
int M = original.PixelWidth;
int N = original.PixelHeight;
int m = (int)Math.Round(M * scale);
int n = (int)Math.Round(N * scale);
byte[] arrayOriginal;
using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, ms);
encoder.SetSoftwareBitmap(original);
await encoder.FlushAsync();
arrayOriginal = new byte[ms.Size];
await ms.ReadAsync(arrayOriginal.AsBuffer(), (uint)ms.Size, InputStreamOptions.None);
}
byte[] arrayCropped;
SoftwareBitmap cropped = new SoftwareBitmap(original.BitmapPixelFormat, m, n);
using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, ms);
encoder.SetSoftwareBitmap(cropped);
await encoder.FlushAsync();
arrayCropped = new byte[ms.Size];
await ms.ReadAsync(arrayCropped.AsBuffer(), (uint)ms.Size, InputStreamOptions.None);
}
int tmp = startIndex + 2 * (N - n) * M + 2 * (M - m);
for (int i = 0; i < n; i++)
Array.ConstrainedCopy(arrayOriginal, tmp + 4 * M * i, arrayCropped,4 * m * (n-1-i), 4 * m);
cropped.Dispose();
cropped = SoftwareBitmap.CreateCopyFromBuffer(arrayCropped.AsBuffer(), BitmapPixelFormat.Bgra8, m, n);
return cropped;
}