C#调整位图大小而不改变像素格式
C# Resizing Bitmap without changing the Pixelformat
我有一张 BGR 格式的位图,分辨率为 1920*1200,我想在不更改像素格式的情况下对其进行缩放。
private Bitmap rescale(Size size, Bitmap origin)
{
Bitmap scaled = new Bitmap(origin, size);
return scaled;
}
问题是,缩放后的结果是一个 RGBA 位图(所有 alpha 均为 255),这不仅对我没用,而且还让我很烦恼,因为后来我在不同的平台上做 AbsDiff(来自 EMGU)图像,然后,alpha 值总是变成零..
有没有办法在缩放时不更改像素格式或在没有 alpha 值的情况下执行 AbsDiff?因为像这样,我后面加载图片的时候,它是不可见的..
这似乎是您需要的:
http://www.codeproject.com/Tips/552141/Csharp-Image-resize-convert-and-save
和
public Bitmap(
Image original,
Size newSize
)
这是一个采用新大小的构造函数。图像会自动调整为该大小。
我这样做的(诚然有点丑)方法是使用原始像素格式和新大小创建一个新位图,然后在其上绘制原始位图(未经测试):
private Bitmap rescale(Size size, Bitmap origin)
{
Bitmap rescaled = new Bitmap(size.Width, size.Height, origin.PixelFormat);
using(Graphics g = Graphics.FromImage(rescaled))
{
g.DrawImage(origin, 0, 0, size.Width, size.Height);
}
return rescaled;
}
Bitmap scaled = new Bitmap(origin, size);
构造函数调用中内置了很多隐含的假设。你会得到:
- 具有 32bppPArgb 像素格式的位图。旨在帮助程序员陷入成功的陷阱,它是现代 PC 上最优化的像素格式。兼容视频适配器帧缓冲区的像素格式,无需任何转换即可进行位块传输。它比所有其他的快 十 倍。
- 分辨率设置为视频适配器 DPI。这通常不太理想,尽管很难说它应该在重新缩放后使用源图像的分辨率。您可能想要修改它。
- 透明背景。如果源位图具有透明度或像素的 alpha 通道设置为值 < 255,这很重要。通常很好,如果源位图是透明的,那么新位图也将是透明的。 alpha 不太好,重新缩放位图很可能会对它产生负面影响。 YMMV.
- 源图像的双线性插值。这是相当适度的,您可能希望 InterpolationMode.HighQualityBicubic 获得更好的结果,尤其是当您将其缩小超过 50% 时。或 NearestNeighbor,如果您关心速度或源图像非常小并且您将其放大以保持像素可见。
很明显你不开心,第一颗子弹就是你抱怨的来源。将所有细节都写出来:
public static Bitmap RescaleImage(Image source, Size size) {
// 1st bullet, pixel format
var bmp = new Bitmap(size.Width, size.Height, source.PixelFormat);
// 2nd bullet, resolution
bmp.SetResolution(source.HorizontalResolution, source.VerticalResolution);
using (var gr = Graphics.FromImage(bmp)) {
// 3rd bullet, background
gr.Clear(Color.Transparent);
// 4th bullet, interpolation
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
gr.DrawImage(source, new Rectangle(0, 0, size.Width, size.Height));
}
return bmp;
}
-
我有一张 BGR 格式的位图,分辨率为 1920*1200,我想在不更改像素格式的情况下对其进行缩放。
private Bitmap rescale(Size size, Bitmap origin)
{
Bitmap scaled = new Bitmap(origin, size);
return scaled;
}
问题是,缩放后的结果是一个 RGBA 位图(所有 alpha 均为 255),这不仅对我没用,而且还让我很烦恼,因为后来我在不同的平台上做 AbsDiff(来自 EMGU)图像,然后,alpha 值总是变成零.. 有没有办法在缩放时不更改像素格式或在没有 alpha 值的情况下执行 AbsDiff?因为像这样,我后面加载图片的时候,它是不可见的..
这似乎是您需要的: http://www.codeproject.com/Tips/552141/Csharp-Image-resize-convert-and-save
和
public Bitmap(
Image original,
Size newSize
)
这是一个采用新大小的构造函数。图像会自动调整为该大小。
我这样做的(诚然有点丑)方法是使用原始像素格式和新大小创建一个新位图,然后在其上绘制原始位图(未经测试):
private Bitmap rescale(Size size, Bitmap origin)
{
Bitmap rescaled = new Bitmap(size.Width, size.Height, origin.PixelFormat);
using(Graphics g = Graphics.FromImage(rescaled))
{
g.DrawImage(origin, 0, 0, size.Width, size.Height);
}
return rescaled;
}
Bitmap scaled = new Bitmap(origin, size);
构造函数调用中内置了很多隐含的假设。你会得到:
- 具有 32bppPArgb 像素格式的位图。旨在帮助程序员陷入成功的陷阱,它是现代 PC 上最优化的像素格式。兼容视频适配器帧缓冲区的像素格式,无需任何转换即可进行位块传输。它比所有其他的快 十 倍。
- 分辨率设置为视频适配器 DPI。这通常不太理想,尽管很难说它应该在重新缩放后使用源图像的分辨率。您可能想要修改它。
- 透明背景。如果源位图具有透明度或像素的 alpha 通道设置为值 < 255,这很重要。通常很好,如果源位图是透明的,那么新位图也将是透明的。 alpha 不太好,重新缩放位图很可能会对它产生负面影响。 YMMV.
- 源图像的双线性插值。这是相当适度的,您可能希望 InterpolationMode.HighQualityBicubic 获得更好的结果,尤其是当您将其缩小超过 50% 时。或 NearestNeighbor,如果您关心速度或源图像非常小并且您将其放大以保持像素可见。
很明显你不开心,第一颗子弹就是你抱怨的来源。将所有细节都写出来:
public static Bitmap RescaleImage(Image source, Size size) {
// 1st bullet, pixel format
var bmp = new Bitmap(size.Width, size.Height, source.PixelFormat);
// 2nd bullet, resolution
bmp.SetResolution(source.HorizontalResolution, source.VerticalResolution);
using (var gr = Graphics.FromImage(bmp)) {
// 3rd bullet, background
gr.Clear(Color.Transparent);
// 4th bullet, interpolation
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
gr.DrawImage(source, new Rectangle(0, 0, size.Width, size.Height));
}
return bmp;
}
-
-