C# 从1bpp位图生成1bpp PCX时出现问题
我有一个类,它可以工作8个bpp到pcx的位图,但是我很难让它工作1个bpp 图像开始时如下所示: 但在第27行之后生成的PCX为黑色,如IrfanView中所示: 有人能帮我找出那个明显的错误吗 顺便说一下,用法是C# 从1bpp位图生成1bpp PCX时出现问题,c#,bmp,pcx,C#,Bmp,Pcx,我有一个类,它可以工作8个bpp到pcx的位图,但是我很难让它工作1个bpp 图像开始时如下所示: 但在第27行之后生成的PCX为黑色,如IrfanView中所示: 有人能帮我找出那个明显的错误吗 顺便说一下,用法是Pcx.SavePCX(“AOut.Pcx”,新位图(“A.bmp”) 使用系统; 使用系统诊断; 使用系统图; 使用系统、绘图、成像; 使用System.IO; 使用System.Runtime.InteropServices; 名称空间映像 { 公共密封类Pcx { 私有静态
Pcx.SavePCX(“AOut.Pcx”,新位图(“A.bmp”)代码>
使用系统;
使用系统诊断;
使用系统图;
使用系统、绘图、成像;
使用System.IO;
使用System.Runtime.InteropServices;
名称空间映像
{
公共密封类Pcx
{
私有静态void WriteWord(流、整型数据)
{
stream.WriteByte((字节)(data&0xFF));
stream.WriteByte((字节)((数据>>8)和0xFF));
}
公共静态void SavePCX(流pcxStream、位图bmp)
{
如果(bmp.PixelFormat!=PixelFormat.format1bppingdexed)
{
抛出新异常(“只能创建1bpp索引的PCX位图”);
}
var data=bmp.LockBits(新矩形(0,0,bmp.Width,bmp.Height),ImageLockMode.ReadOnly,bmp.PixelFormat);
尝试
{
{
//标题
pcxStream.WriteByte(10);//字符制造商;
pcxStream.WriteByte(5);//字符版本;
pcxStream.WriteByte(1);//字符编码;
pcxStream.WriteByte(1);//字符bpp;
pcxStream.WriteByte(0);
pcxStream.WriteByte(0);//字符xmin[2];
pcxStream.WriteByte(0);
pcxStream.WriteByte(0);//字符ymin[2];
WriteWord(pcxStream,bmp.Width-1);//字符xmax[2];
WriteWord(pcxStream,bmp.Height-1);//char-ymax[2];
WriteWord(pcxStream,72);//word(pcx->hdpi,72);
WriteWord(pcxStream,72);//word(pcx->vdpi,72);
对于(var i=0;i<16*3;i++)//4bpp调色板
{
pcxStream.WriteByte(0);
}
pcxStream.WriteByte(0);//pcx->res=0;
pcxStream.WriteByte(1);//pcx->nplanes=1;
WriteWord(pcxStream,bmp.Width);//word(pcx->bytesperline,Width/2);
WriteWord(pcxStream,0);//word(pcx->palletteinfo,0);
WriteWord(pcxStream,0);//word(pcx->hscrn,0);
WriteWord(pcxStream,0);//word(pcx->vscrn,0);
对于(vari=0;i<54;i++)//memset(pcx->filler,0,54);
{
pcxStream.WriteByte(0);
}
}//头的末尾
{
//将所有字节读取到数组
var基线=data.Scan0;
//声明一个数组以保存位图的字节。
var bytellength=bmp.Width*bmp.Height;
var字节=新字节[字节长度];
//将RGB值复制到数组中。
对于(变量y=0;y1)| |(ld>=0xC0))pcxStream.WriteByte((byte)(0xC0 | run));
pcxStream.WriteByte(ld);
}
run=1;
}
ldata=字节[baseIdx];
baseIdx++;
}
ld=(字节)((ldata>>4)|(ldata 1)|(ld>=0xC0))pcxStream.WriteByte((字节)(0xC0 | run));
pcxStream.WriteByte(ld);
}
}
最后
{
解锁位(数据);
}
}
公共静态void SavePCX(字符串文件名,位图bbp1Bmp)
{
使用(var fstest=newfilestream(文件名,FileMode.Create,FileAccess.Write))
{
SavePCX(fstest,bbp1Bmp);
}
}
}
}
通过使用数据解决了这个问题。对于每行的字节,使用跨步
读取1bpp中的字节,使用跨步作为宽度,而不是宽度
public static void SavePCX(Stream pcxStream, Bitmap bmp)
{
if (bmp.PixelFormat != PixelFormat.Format1bppIndexed)
{
throw new Exception("Can only PCX bitmaps that are 1bpp indexed");
}
var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
try
{
{
//header
pcxStream.WriteByte(10); // char manufacturer;
pcxStream.WriteByte(5); //char version;
pcxStream.WriteByte(1); //char encoding;
pcxStream.WriteByte(1); // char bpp;
pcxStream.WriteByte(0);
pcxStream.WriteByte(0); //char xmin[2];
pcxStream.WriteByte(0);
pcxStream.WriteByte(0); //char ymin[2];
WriteWord(pcxStream, bmp.Width - 1); // char xmax[2];
WriteWord(pcxStream, bmp.Height - 1); //char ymax[2];
WriteWord(pcxStream, 72); //word(pcx->hdpi, 72);
WriteWord(pcxStream, 72); // word(pcx->vdpi, 72);
for (var i = 0; i < 16*3; i++) //4bpp palette
{
pcxStream.WriteByte(0);
}
pcxStream.WriteByte(0); // pcx->res = 0;
pcxStream.WriteByte(1); // pcx->nplanes = 1;
WriteWord(pcxStream, data.Stride); // word(pcx->bytesperline, width / 2);
WriteWord(pcxStream, 0); //word(pcx->palletteinfo, 0);
WriteWord(pcxStream, 0); //word(pcx->hscrn, 0);
WriteWord(pcxStream, 0); //word(pcx->vscrn, 0);
for (var i = 0; i < 54; i++) //memset(pcx->filler, 0, 54);
{
pcxStream.WriteByte(0);
}
} //end of header
{
//read all bytes to an array
var baseLine = data.Scan0;
// Declare an array to hold the bytes of the bitmap.
var byteLength = data.Stride*data.Height;
var bytes = new byte[byteLength];
// Copy the RGB values into the array.
for (var y = 0; y < data.Height; y++)
{
var lineOffset = y*data.Stride;
Debug.WriteLine("Y={0}, Offset={1}", y, lineOffset);
for (var x = 0; x < data.Stride; x++)
{
bytes[y*data.Stride + x] = Marshal.ReadByte(baseLine, lineOffset + x);
}
}
var baseIdx = 0;
var end = byteLength;
var run = 0;
var ldata = -1;
byte ld;
while (baseIdx < end)
{
//if it matches, increase the run by 1 up to max of 63
if ((bytes[baseIdx] == ldata) && (run < 63)) run++;
else
{
//write data
if (run != 0) //not first run
{
ld = (byte) ldata;
if ((run > 1) || (ld >= 0xC0)) pcxStream.WriteByte((byte) (0xC0 | run));
pcxStream.WriteByte(ld);
}
run = 1;
}
ldata = bytes[baseIdx];
baseIdx++;
}
ld = (byte) ((ldata >> 4) | (ldata << 4));
if ((run > 1) || (ld >= 0xC0)) pcxStream.WriteByte((byte) (0xC0 | run));
pcxStream.WriteByte(ld);
}
}
finally
{
bmp.UnlockBits(data);
}
}
publicstaticvoidsavepcx(流pcxStream,位图bmp)
{
如果(bmp.PixelFormat!=PixelFormat.format1bppingdexed)
{
抛出新异常(“只能创建1bpp索引的PCX位图”);
}
var data=bmp.LockBits(新矩形(0,0,bmp.Width,bmp.Height),ImageLockMode.ReadOnly,bmp.PixelFormat);
尝试
{
{
//标题
pcxStream.WriteByte(10);//字符制造商;
pcxStream.WriteByte(5);//字符版本;
pcxStream.WriteByte(1);//字符编码;
pcxStream.WriteByte(1);//字符bpp;
pcxStream.WriteByte(0);
pcxStream.WriteByte(0);//字符xmin[2];
public static void SavePCX(Stream pcxStream, Bitmap bmp)
{
if (bmp.PixelFormat != PixelFormat.Format1bppIndexed)
{
throw new Exception("Can only PCX bitmaps that are 1bpp indexed");
}
var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
try
{
{
//header
pcxStream.WriteByte(10); // char manufacturer;
pcxStream.WriteByte(5); //char version;
pcxStream.WriteByte(1); //char encoding;
pcxStream.WriteByte(1); // char bpp;
pcxStream.WriteByte(0);
pcxStream.WriteByte(0); //char xmin[2];
pcxStream.WriteByte(0);
pcxStream.WriteByte(0); //char ymin[2];
WriteWord(pcxStream, bmp.Width - 1); // char xmax[2];
WriteWord(pcxStream, bmp.Height - 1); //char ymax[2];
WriteWord(pcxStream, 72); //word(pcx->hdpi, 72);
WriteWord(pcxStream, 72); // word(pcx->vdpi, 72);
for (var i = 0; i < 16*3; i++) //4bpp palette
{
pcxStream.WriteByte(0);
}
pcxStream.WriteByte(0); // pcx->res = 0;
pcxStream.WriteByte(1); // pcx->nplanes = 1;
WriteWord(pcxStream, data.Stride); // word(pcx->bytesperline, width / 2);
WriteWord(pcxStream, 0); //word(pcx->palletteinfo, 0);
WriteWord(pcxStream, 0); //word(pcx->hscrn, 0);
WriteWord(pcxStream, 0); //word(pcx->vscrn, 0);
for (var i = 0; i < 54; i++) //memset(pcx->filler, 0, 54);
{
pcxStream.WriteByte(0);
}
} //end of header
{
//read all bytes to an array
var baseLine = data.Scan0;
// Declare an array to hold the bytes of the bitmap.
var byteLength = data.Stride*data.Height;
var bytes = new byte[byteLength];
// Copy the RGB values into the array.
for (var y = 0; y < data.Height; y++)
{
var lineOffset = y*data.Stride;
Debug.WriteLine("Y={0}, Offset={1}", y, lineOffset);
for (var x = 0; x < data.Stride; x++)
{
bytes[y*data.Stride + x] = Marshal.ReadByte(baseLine, lineOffset + x);
}
}
var baseIdx = 0;
var end = byteLength;
var run = 0;
var ldata = -1;
byte ld;
while (baseIdx < end)
{
//if it matches, increase the run by 1 up to max of 63
if ((bytes[baseIdx] == ldata) && (run < 63)) run++;
else
{
//write data
if (run != 0) //not first run
{
ld = (byte) ldata;
if ((run > 1) || (ld >= 0xC0)) pcxStream.WriteByte((byte) (0xC0 | run));
pcxStream.WriteByte(ld);
}
run = 1;
}
ldata = bytes[baseIdx];
baseIdx++;
}
ld = (byte) ((ldata >> 4) | (ldata << 4));
if ((run > 1) || (ld >= 0xC0)) pcxStream.WriteByte((byte) (0xC0 | run));
pcxStream.WriteByte(ld);
}
}
finally
{
bmp.UnlockBits(data);
}
}