我正在玩交换图像的颜色值,但我似乎找到了一些我不太了解的东西 - 而且我似乎无法在谷歌上找到关于这个问题的好读物。我可以完成交换图像的颜色,但它也会改变输出文件的大小,与输入文件的大小相比。
以下是我为测试此事而编写的测试类,以及它的作用,总结如下:
代码如下所示:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace GraphTheory
{
class Test
{
public Test(Bitmap bmp)
{
#region Assign bitmap to memory
// Rectangle to hold the bmp.
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
// Lock the bitmap to the rectangle / system memory.
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
// Get the adress of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] rgb = new byte[bytes];
// Copy the RGB values of the bitmap into the array.
Marshal.Copy(ptr, rgb, 0, bytes);
#endregion
#region Split rgb array into three arrays
// Number of colors in the image.
int colors = bytes / 3;
// Declare three arrays to hold the RGB values of the bitmap.
byte[] r = new byte[colors];
byte[] g = new byte[colors];
byte[] b = new byte[colors];
// Set starting pos of color index.
int colorIndex = 0;
// Split the array of RGB values into three seperate arrays.
for (int i = 0; i < rgb.Length; i += 3)
{
int j = i + 1, k = i + 2;
r[colorIndex] = rgb[k];
g[colorIndex] = rgb[j];
b[colorIndex] = rgb[i];
colorIndex++;
}
#endregion
#region Hide data in the colors of the bitmap
for (int i = 0; i < colors; i += 2)
{
switchBits(ref r[i], ref r[i + 1]);
}
#endregion
#region Join the three arrays into one rgb array
// Reset color index.
colorIndex = 0;
// Replace the values of the rgb array with the values of the r, g and b arrays.
for (int i = 0; i < rgb.Length; i += 3)
{
int j = i + 1, k = i + 2;
rgb[k] = r[colorIndex];
rgb[j] = g[colorIndex];
rgb[i] = b[colorIndex];
colorIndex++;
}
#endregion
#region Free bitmap from memory and save to file
// Copy the RGB values back to the bitmap
Marshal.Copy(rgb, 0, ptr, bytes);
// Unlock the bits.
bmp.UnlockBits(bmpData);
// Export the image.
bmp.Save("../../output.png");
#endregion
}
private void switchBits(ref byte bit1, ref byte bit2)
{
byte tmp = bit1;
bit1 = bit2;
bit2 = tmp;
}
}
}
我根本不明白为什么会改变位图的图像大小,因为我没有替换任何颜色值,只是重新排列它们。
输入文件的大小:[884 KB]
输出文件的大小:[1335 KB]
没有图片不包含Alpha通道:
Image.IsAlphaPixelFormat(image.PixelFormat) == false
答案 0 :(得分:1)
PNG使用(无损)压缩。这意味着输出文件的大小取决于您提供的数据。压缩利用数据中的冗余并通过删除它,可以实现更小的尺寸。图像倾向于具有大量冗余,因为相邻像素是相关的,即它们具有相似的值。在你的情况下发生的事情是你的洗牌有点干扰图像的自然图案,从而减少像素相关性和减少。因此,在压缩数据时,它们会占用更多空间。
如果你要对所有组件进行洗牌,我不会感到惊讶,你会发现输出大小的增长甚至超过仅仅改变红色的大小。
答案 1 :(得分:0)
您对alpha的检查是针对图片的,而不是保存的内容。默认情况下,PNG将保存alpha。请尝试: