【发布时间】:2016-08-13 19:42:46
【问题描述】:
我正在尝试交换图像的颜色值,但我似乎发现了一些我不太理解的东西 - 我似乎无法在谷歌上找到关于此事的好读物。我可以完成图像颜色的交换,但与输入文件的大小相比,它也会改变输出文件的大小。
下面是我写的一个测试类来测试这个问题,它的作用,总结就是:
- 将位图分配给内存。
- 制作一个 RGB 值数组。
- 将 RGB 值数组拆分为三个单独的数组(r、g 和 b)。
- 用红色交换所有值(r[0] r[1]、r[2] r[3] 等)
- 加入三个数组并分配给 RGB 值数组。
- 复制回位图。
- 释放分配的内存。
- 导出文件。
代码如下:
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
【问题讨论】:
-
输入输出文件是什么格式的?
-
输入和输出都是 .png 格式。我将位图加载为:
Bitmap bmp = new Bitmap("../../input.png");并将其导出为bmp.Save("../../output.png");@Reti43 -
而如果你加载输入文件并立即保存而不修改,它会和原来一样大小吗?
-
对 5 个不同大小的不同测试文件测试为阳性,所以结论是:是的。
标签: c# bitmap steganography