我使用此代码来减少图像的深度:
public void ApplyDecreaseColourDepth(int offset)
{
int A, R, G, B;
Color pixelColor;
for (int y = 0; y < bitmapImage.Height; y++)
{
for (int x = 0; x < bitmapImage.Width; x++)
{
pixelColor = bitmapImage.GetPixel(x, y);
A = pixelColor.A;
R = ((pixelColor.R + (offset / 2)) - ((pixelColor.R + (offset / 2)) % offset) - 1);
if (R < 0)
{
R = 0;
}
G = ((pixelColor.G + (offset / 2)) - ((pixelColor.G + (offset / 2)) % offset) - 1);
if (G < 0)
{
G = 0;
}
B = ((pixelColor.B + (offset / 2)) - ((pixelColor.B + (offset / 2)) % offset) - 1);
if (B < 0)
{
B = 0;
}
bitmapImage.SetPixel(x, y, Color.FromArgb(A, R, G, B));
}
}
}
第一个问题是:我给函数的偏移量不是深度,是吗?
第二个是当我在减少颜色深度后尝试保存图像时,我获得与原始图像相同的大小。我不应该得到一个尺寸较小的文件,或者我错了。
这是我用来保存修改后图像的代码:
private Bitmap bitmapImage;
public void SaveImage(string path)
{
bitmapImage.Save(path);
}
答案 0 :(得分:4)
您只是将像素值设置为较低级别。
例如,如果一个像素由3个通道表示,每个通道16位,则将每个像素颜色值减少到每通道8位。这将永远不会减小图像大小,因为分配的像素已经具有16位的固定深度。 尝试将新值保存到最大为8位深度的新图像 当然,您将以字节为单位缩小图像,但不会影响整体尺寸,即图像的X,Y尺寸将保持不变。你在做什么会降低图像质量。
答案 1 :(得分:2)
让我们首先清理一下代码。以下模式:
R = ((pixelColor.R + (offset / 2)) - ((pixelColor.R + (offset / 2)) % offset) - 1);
if (R < 0)
{
R = 0;
}
等同于:
R = Math.Max(0, (pixelColor.R + offset / 2) / offset * offset - 1);
您可以简化您的功能:
public void ApplyDecreaseColourDepth(int offset)
{
for (int y = 0; y < bitmapImage.Height; y++)
{
for (int x = 0; x < bitmapImage.Width; x++)
{
int pixelColor = bitmapImage.GetPixel(x, y);
int A = pixel.A;
int R = Math.Max(0, (pixelColor.R + offset / 2) / offset * offset - 1);
int G = Math.Max(0, (pixelColor.G + offset / 2) / offset * offset - 1);
int B = Math.Max(0, (pixelColor.B + offset / 2) / offset * offset - 1);
bitmapImage.SetPixel(x, y, Color.FromArgb(A, R, G, B));
}
}
}
回答你的问题:
答案 2 :(得分:1)
首先,我想问你一个简单的问题:)
int i = 10;
现在i = i - ;
它对我的大小有影响吗? ans是否。
你正在做同样的事情
成像的索引表示在两个矩阵中 1用于颜色映射和 2来自图像映射
您只需更改元素的值而不删除它 所以它不会影响图像的大小
答案 3 :(得分:1)
使用Get / SetPixel无法降低颜色深度。这些方法只会改变颜色。
您似乎无法轻松将图像保存为某种像素格式,但我确实找到了一些代码来更改内存中的像素格式。您可以尝试保存它,它可能会起作用,具体取决于您保存的格式。
从这个问题:https://stackoverflow.com/a/2379838/785745
他给出了这个代码来改变颜色深度:
public static Bitmap ConvertTo16bpp(Image img) {
var bmp = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
using (var gr = Graphics.FromImage(bmp))
{
gr.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));
}
return bmp;
}
您可以将代码中的PixelFormat更改为您需要的任何内容。
答案 4 :(得分:0)
某个像素计数的位图图像始终大小相同,因为位图格式不应用压缩。 如果您使用算法(例如JPEG)压缩图像,则缩小&#39;图像应该更小。
R = ((pixelColor.R + (offset / 2)) - ((pixelColor.R + (offset / 2))
这不总是返回0吗?
答案 5 :(得分:0)
如果要缩小图像的大小,可以在调用Image.Save()时指定其他压缩格式。
GIF文件格式可能是一个很好的选择,因为它最适用于相同颜色的连续像素(当颜色深度较低时更常出现)。
JPEG可以很好地处理照片,但是如果将24位图像转换为16位图像然后使用JPEG对其进行压缩,则不会看到明显的结果,因为算法的工作方式(你更好)关闭将24位图片直接保存为JPEG。
正如其他人所解释的那样,除非您将结果数据实际复制到另一个具有Format16bppRgb555
{{1}} {{}}}的Bitmap对象,否则您的代码不会减小Image对象使用的大小。< / p>