//SFFV2 从组和编码获取图像数据 public byte[] getSprDataV2(int group, int index, FI_FORMAT type) { sprMsgV2 spr; for (int i = 0; i < msgV2.sprNum; i++) { spr = getSprMsgV2(i); if (spr.group == group && spr.index == index) { //转移事件 return(getSprDataV2(i, type)); } } return(null); }
public static IntPtr LoadFromMemory(byte[] sprData, FI_FORMAT type) { //读图像数据并储存在非托管内存 IntPtr sprPoint = Marshal.AllocHGlobal(sprData.Length); Marshal.Copy(sprData, 0, sprPoint, sprData.Length); //从非托管内存提交给FreeImage int sprStream = FI.OpenMemory((int)sprPoint, sprData.Length); IntPtr dib = FI.LoadFromMemory(type, sprStream, 0); //释放 Marshal.FreeHGlobal(sprPoint); FI.CloseMemory(sprStream); return(dib); }
//SFFV1 从组和编号获取图像数据 public byte[] getSprDataV1(int group, int index, FI_FORMAT type) { int offset = msgV1.sprOffset; for (int i = 0; i < msgV1.sprNum; i++) { seek(offset); offset = br.ReadInt32(); seek(8, SeekOrigin.Current); if (br.ReadUInt16() == group && br.ReadUInt16() == index) { //转移事件 return(getSprDataV1(i, type)); } } return(null); }
public static bool SaveToMemory(IntPtr dib, ref byte[] sprData, FI_FORMAT type) { //保存图像到流 int newSprStream = FI.OpenMemory(0, 0); if (FI.SaveToMemory(type, dib, newSprStream, 0) == false) { return(false); } //将非托管数据重新转为托管类型 int newSprPoint = 0; int newLen = 0; FI.AcquireMemory(newSprStream, ref newSprPoint, ref newLen); sprData = new byte[newLen]; Marshal.Copy((IntPtr)newSprPoint, sprData, 0, newLen); //释放 FI.CloseMemory(newSprStream); return(true); }
private static extern bool SaveToMemory(FI_FORMAT fif, IntPtr dib, int stream, int flag);
private static extern IntPtr LoadFromMemory(FI_FORMAT fif, int stream, int Flag);
//SFFV2 从索引获取图像数据 public byte[] getSprDataV2(int index, out byte[] pp, FI_FORMAT type, bool loadPal = true) { byte[] sprData; byte[] palData = null; int sprSize; IntPtr dib; sprMsgV2 spr = getSprMsgV2(index); if (spr.dataLen == 0) { //链接型图像 return(getSprDataV2(spr.linkIndex, out pp, type)); } seek((spr.flags == 1 ? msgV2.tdataOffset : msgV2.ldataOffset) + spr.dataOffset); //压缩算法(fmt)常量声明这里省略了,直接使用值 //0 无压缩 //2 Rle8压缩 //3 Rle5压缩 几乎不会用到 直接省略 //4 Lz5压缩 //10 PNG8 //11 PNG24 //12 PNG32 if (spr.fmt == 0) { sprData = br.ReadBytes(spr.dataLen); } else { sprSize = br.ReadInt32(); //解压后的校验长度,这里省略了校验 sprData = br.ReadBytes(spr.dataLen - 4); } switch (spr.fmt) { case 0: if (loadPal) { palData = getPalData(spr.palIndex); } pp = palData; break; case 2: sprData = sffV2Decompress.unRle8(sprData); if (loadPal) { palData = getPalData(spr.palIndex); } pp = palData; break; case 4: sprData = sffV2Decompress.unLz5(sprData); if (loadPal) { palData = getPalData(spr.palIndex); } pp = palData; break; case 10: //压缩算法为PNG算法时读取的数据默认都是一个完整的PNG文件 可以直接载入 palData = getPalData(spr.palIndex); dib = FI.LoadFromMemory(sprData, FI_FORMAT.FIF_PNG); //PNG8调色板校正 RGBQUAD *pale = FI.GetPalette(dib); for (int n = 0; n < 256; n++) { pale [n].Red = palData [n * 4]; pale [n].Green = palData [n * 4 + 1]; pale [n].Blue = palData [n * 4 + 2]; } FI.SaveToMemory(dib, ref sprData, type); pp = palData; return(sprData); case 11: case 12: pp = null; return(sprData); default: sprData = new byte[0]; pp = new byte[0]; return(sprData); } if (type != FI_FORMAT.FIF_UNKNOWN) { //对于无压缩、Rle8和Lz5压缩的图像读取的数据是原始的像素数据 不能直接载入 dib = FI.ConvertFromRawBits(sprData, spr.width, spr.height, spr.width, 8, 0, 0, 0, true); RGBQUAD *pal = FI.GetPalette(dib); int colorNum = palData.Length / 4; for (int n = 0; n < colorNum; n++) { pal [n].Red = palData [n * 4]; pal [n].Green = palData [n * 4 + 1]; pal [n].Blue = palData [n * 4 + 2]; } FI.SaveToMemory(dib, ref sprData, type); FI.Free(dib); return(sprData); } else { return(sprData); } }
//SFFV1 从索引获取指定图像数据 public byte[] getSprDataV1(int index, out byte[] pp, FI_FORMAT type) { int offset = msgV1.sprOffset; sprMsgV1 spr = new sprMsgV1(); byte[] facePalData = new byte[0]; byte[] palData = new byte[0]; byte[] sprData = new byte[0]; for (int i = 0; i < msgV1.sprNum; i++) { seek(offset); offset = br.ReadInt32(); spr.pcxDataLen = br.ReadInt32(); spr.x = br.ReadInt16(); spr.y = br.ReadInt16(); spr.group = br.ReadUInt16(); spr.index = br.ReadUInt16(); spr.linkIndex = br.ReadUInt16(); spr.palType = br.ReadByte(); if (i == 0) { //第一张图强制为独立色表 spr.palType = 0; } seek(13, SeekOrigin.Current); if ((spr.group == 0 && spr.index == 0 || spr.group == 9000 && spr.index == 0) && facePalData.Length != 0) { //0,0和9000,0强制为独立色表,且使用第一张色表 palData = facePalData; } if (i == index) { if (spr.pcxDataLen == 0) { //链接型图像 return(getSprDataV1(spr.linkIndex, out pp, type)); } sprData = br.ReadBytes(spr.pcxDataLen); if (type != FI_FORMAT.FIF_UNKNOWN) { IntPtr dib = FI.LoadFromMemory(sprData, FI_FORMAT.FIF_PCX); if (spr.palType == 1) { RGBQUAD *pal = FI.GetPalette(dib); for (int n = 0; n < 256; n++) { pal[n].Red = palData[n * 3]; pal[n].Green = palData[n * 3 + 1]; pal[n].Blue = palData[n * 3 + 2]; } } FI.SaveToMemory(dib, ref sprData, type); //释放图像流 FI.Free(dib); } pp = palData; return(sprData); } else { if (spr.palType == 0) { //读取PCX尾部色表数据 seek(spr.pcxDataLen - 768, SeekOrigin.Current); palData = br.ReadBytes(768); if (i == 0) { //保留第一张图的色表 facePalData = palData; } } } } pp = null; return(null); }