为什么在 Image 上旋转比使用 BitmapEncoder 快得多?
Why is rotation much faster on Image than using BitmapEncoder?
使用
旋转图像
image.RenderTransform = new RotateTransform()...
几乎是立竿见影的。
另一方面,使用
bitmapEncoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees...
比 慢很多(在 FlushAsync()
中)- 超过半秒。
这是为什么?有没有办法利用快速旋转来旋转位图?
第一个image.RenderTransform
将使用硬件渲染来渲染位图。 (GPU) 图像不旋转但会显示 rotated/scaled。 (将仅直接访问可见像素 from/in 视频内存)
第二个会将图像本身旋转 CPU(所有像素)。它将为结果创建新的内存。 (非显存)
更新:
Is there a way to use the GPU to edit bitmaps?
Depends on what you need:
如果你想使用GPU。您可以使用托管包装器(如 Slim DX/Sharp DX)这将需要很长时间才能获得结果。别忘了,通过 gpu 重新栅格化图像可能会导致质量下降。
如果只想旋转图像(0、90、180、270)?您可以使用带有 de ScanLine0 选项的位图 class。 (这是为了保持质量和大小)并且您可以创建一个快速的实现。
看这里:
Fast work with Bitmaps in C#
我会为每个角度 (0,90,180,270) 创建一个算法。因为你不想计算每个像素的 x, y 位置。如下所示..
提示:
努力输掉multiplies/divides.
/*This time we convert the IntPtr to a ptr*/
byte* scan0 = (byte*)bData.Scan0.ToPointer();
for (int i = 0; i < bData.Height; ++i)
{
for (int j = 0; j < bData.Width; ++j)
{
byte* data = scan0 + i * bData.Stride + j * bitsPerPixel / 8;
//data is a pointer to the first byte of the 3-byte color data
}
}
变成类似:
/*This time we convert the IntPtr to a ptr*/
byte* scan0 = (byte*)bData.Scan0.ToPointer();
byte* data = scan0;
int bytesPerPixel = bitsPerPixel / 8;
for (int i = 0; i < bData.Height; ++i)
{
byte* data2 = data;
for (int j = 0; j < bData.Width; ++j)
{
//data2 is a pointer to the first byte of the 3-byte color data
data2 += bytesPerPixel;
}
data += bData.Stride;
}
使用
旋转图像image.RenderTransform = new RotateTransform()...
几乎是立竿见影的。 另一方面,使用
bitmapEncoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees...
比 慢很多(在 FlushAsync()
中)- 超过半秒。
这是为什么?有没有办法利用快速旋转来旋转位图?
第一个image.RenderTransform
将使用硬件渲染来渲染位图。 (GPU) 图像不旋转但会显示 rotated/scaled。 (将仅直接访问可见像素 from/in 视频内存)
第二个会将图像本身旋转 CPU(所有像素)。它将为结果创建新的内存。 (非显存)
更新:
Is there a way to use the GPU to edit bitmaps? Depends on what you need:
如果你想使用GPU。您可以使用托管包装器(如 Slim DX/Sharp DX)这将需要很长时间才能获得结果。别忘了,通过 gpu 重新栅格化图像可能会导致质量下降。
如果只想旋转图像(0、90、180、270)?您可以使用带有 de ScanLine0 选项的位图 class。 (这是为了保持质量和大小)并且您可以创建一个快速的实现。
看这里: Fast work with Bitmaps in C#
我会为每个角度 (0,90,180,270) 创建一个算法。因为你不想计算每个像素的 x, y 位置。如下所示..
提示:
努力输掉multiplies/divides.
/*This time we convert the IntPtr to a ptr*/
byte* scan0 = (byte*)bData.Scan0.ToPointer();
for (int i = 0; i < bData.Height; ++i)
{
for (int j = 0; j < bData.Width; ++j)
{
byte* data = scan0 + i * bData.Stride + j * bitsPerPixel / 8;
//data is a pointer to the first byte of the 3-byte color data
}
}
变成类似:
/*This time we convert the IntPtr to a ptr*/
byte* scan0 = (byte*)bData.Scan0.ToPointer();
byte* data = scan0;
int bytesPerPixel = bitsPerPixel / 8;
for (int i = 0; i < bData.Height; ++i)
{
byte* data2 = data;
for (int j = 0; j < bData.Width; ++j)
{
//data2 is a pointer to the first byte of the 3-byte color data
data2 += bytesPerPixel;
}
data += bData.Stride;
}