Get encoder clsid

本文介绍了CTools::GetEncoderClsid函数的功能,用于获取指定格式的图像编码器类ID,包括初始化计数、大小计算、获取编码器信息数组、遍历并返回匹配的类ID。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

int CTools::GetEncoderClsid(const WCHAR *format, CLSID *pClsid)
{
 UINT     num   =   0;                     //   number   of   image   encoders   
 UINT     size   =   0;                   //   size   of   the   image   encoder   array   in   bytes  

 ImageCodecInfo*   pImageCodecInfo   =   NULL;  

 GetImageEncodersSize(&num,   &size);   
 if(size   ==   0)   
  return   -1;     //   Failure  

 pImageCodecInfo   =   (ImageCodecInfo*)(malloc(size));   
 if(pImageCodecInfo   ==   NULL)   
  return   -1;     //   Failure  

 GetImageEncoders(num,   size,   pImageCodecInfo);  

 for(UINT   j   =   0;   j   <   num;   ++j)   
 {   
  if(   wcscmp(pImageCodecInfo[j].MimeType,   format)   ==   0   )   
  {   
   *pClsid   =   pImageCodecInfo[j].Clsid;   
   free(pImageCodecInfo);   
   return   j;     //   Success   
  }           
 }  

 free(pImageCodecInfo);   
 return   -1;     //   Failed 
}

资源分类bin目录 本文解析的是图库类型,配置没什么必要性,在做特效时自行修改就可以了。图库总共7个(有一个重复,实际只有6个) 类型 名字 对应索引 动画配置 Anime_3 AnimeInfo_3 动画配置 Anime_Joy_13 AnimeInfo_Joy_13 动画配置 AnimeEx_1 AnimeInfoEx_1 动画配置 AnimeV3_7 AnimeInfoV3_7 动画配置 Puk2\Anime_PUK2_4 Puk2\AnimeInfo_PUK2_4 动画配置 Puk3\Anime_PUK3_2 Puk3\AnimeInfo_PUK3_2 ??动画配置 AnimeAp AnimeApdd ??战斗调色板 battle_4 battletxt_4 坐标信息 coordinatev3_2 coordinateinfov3_2 声音配置 sound_1 soundaddr_1 图库 Graphic_20 GraphicInfo_20 图库 GraphicEx_4 GraphicInfoEx_4 图库 Graphic_Joy_22 GraphicInfo_20 图库 GraphicV3_18 GraphicInfoV3_18 图库 Puk2\Graphic_PUK2_2 Puk2\GraphicInfo_PUK2_2 图库同Puk2 Puk3\Graphic_PUK2_2 Puk3\GraphicInfo_PUK2_2 图库 Puk3\Graphic_PUK3_1 Puk3\GraphicInfo_PUK3_1 调色板 bin\pal\*.cgp 无 调色板格式 调色板文件固定长度708字节,每个颜色3个字节,总共236个颜色。 游戏中0-15号,240-255号颜色有固定的默认值。调色板实际占据的是16-239号 例如图片使用的调色板为16号颜色,也就是对应调色板文件中的0号颜色。取出字节1(Blue)、字节2(Green)、字节3(Red),自行拼配颜色即可。 本程序默认使用palet_08调色板。 ———————————————— // 索引文件数据块 struct imgInfoHead { unsigned int id; unsigned int addr; // 在图像文件中的偏移 unsigned int len; // 长度 long xOffset; // 在游戏内的偏移量x long yOffset; // 在游戏内的偏移量y unsigned int width; unsigned int height; unsigned char tileEast; // 地图上横向几格 unsigned char tileSouth;// 竖向几格 unsigned char flag; unsigned char unKnow[5]; long tileId; // 所属的地图tile的id }; 索引文件每一张图片包含40个字节的字段。索引文件/40就是总图片数。实际上读取这个索引文件对图片提取没有太大意义,里面的几个字段主要是用于地图的拼接。 图库格式 // 图像bin 文件格式 struct imgData { unsigned char cName[2]; unsigned char cVer; // 1压缩 unsigned char cUnknow; unsigned int width; unsigned int height; unsigned int len; // 包含自身头的总长度,后续跟char数组 }; // + char* len = size - 16 每一张图片都有数据头,而且因为是顺序存储,实际上可以不使用索引文件的。 一张完整的图片包含 数据头+图片数据。 cVer说明: 0:未压缩,后续的数据就是图片数据 1:压缩,需要对后续数据进行解压 3:带调色板的压缩。在读取文件头后,还需要再读入4个字节,这4个字节代表调色板解压后的长度。 取图步骤 读取索引数据 FILE *pFile = nullptr; std::string strPath = _strPath + "\\bin\\"; if (0 == fopen_s(&pFile, (strPath + strInfo).c_str(), "rb")) { imgInfoHead tHead = { 0 }; int len = sizeof(imgInfoHead); while (len == fread_s(&tHead, len, 1, len, pFile)) _vecImginfo.push_back(tHead); } if (pFile) fclose(pFile); ———————————————— 遍历索引读取对应图库数据头 imgData tHead = { 0 }; int len = sizeof(imgData); if (len == fread_s(&tHead, len, 1, len, pFile)) { // 这种是错误的图 if (tHead.width > 5000 || tHead.height > 5000) { saveLog(LOG_ERROR, strErrorFile, strName, "img w or h error", imgHead, tHead); return false; } _cgpLen = 0; // 调色板长度 if (tHead.cVer == 3) { // 多读取4个字节,代表的是调色板的长度 if (4 != fread_s(&_cgpLen, 4, 1, 4, pFile)) { saveLog(LOG_ERROR, strErrorFile, strName, "read cgpLen error", imgHead, tHead); return false; } len += 4; } .... } ———————————————— 解密后续数据 if (imgLen == fread_s(_imgEncode, imgLen, 1, imgLen, pFile)) { if (tHead.cVer == 0) { // 未压缩图片 _imgDataIdx = imgLen; memcpy(_imgData, _imgEncode, imgLen); } else if (tHead.cVer == 1 || tHead.cVer == 3) { // 压缩的图片 _imgDataIdx = decodeImgData(_imgEncode, imgLen); if (_imgDataIdx != tHead.width * tHead.height + _cgpLen) { // 这种情况按说是错的 if (_imgDataIdx < tHead.width * tHead.height + _cgpLen) { saveLog(LOG_ERROR, strErrorFile, strName, "decode len more", imgHead, tHead); return false; } else { // 大于的话应该算是不够严谨 saveLog(LOG_INFO, strErrorFile, strName, "decode len less", imgHead, tHead); } } } } ———————————————— 填充像素 // 默认使用palet_08.cgp(白天) 调色版 unsigned char *pCgp = _uMapCgp.begin()->second.data(); strCgpName = _uMapCgp.begin()->first; // 使用图片自带调色板 if (_cgpLen > 0 && (int)_imgDataIdx >= w * h + _cgpLen) { pCgp = _imgData + (_imgDataIdx - _cgpLen); strCgpName = "self"; } // 图片数据,竖向方向是反的,从最后一行开始 int imgLen = w * h; for (int i = 0; i < imgLen; ++i) { // 调色板编号 int cIdx = _imgData[i] * 3; int idx = (h - i / w - 1) * w + i % w; _imgPixel[idx] = (pCgp[cIdx]) + (pCgp[cIdx + 1] << 8) + (pCgp[cIdx + 2] << 16); if (pCgp[cIdx] != 0 || pCgp[cIdx + 1] != 0 || pCgp[cIdx + 2] != 0) _imgPixel[idx] |= 0xff000000; } ———————————————— 生成图片 Gdiplus::Bitmap bmp(w, h, PixelFormat32bppARGB); int idx = 0; for (int row = 0; row < h; ++row) { for (int col = 0; col < w; ++col) { bmp.SetPixel(col, row, p[idx++]); } } CLSID encoderClsid; std::wstring s = L"image/" + wstrExt; if (!GetEncoderClsid(s.c_str(), &encoderClsid)) { return false; } std::wstring sName = wstrName + L"." + wstrExt; bmp.Save(sName.c_str(), &encoderClsid, nullptr); ———————————————— 依照內容生成BIN檔提取圖片工具 魔力宝贝高清单机计划(一) 图库提取 https://blog.youkuaiyun.com/qq_37543025/article/details/88377553
最新发布
07-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值