念住向GalPhotoAuto加处理*.gal的功能,不过最后因为Gale.spi静系可以返回24位的图片,坑之。
下边代码可以系Visual Studio 2012直接编译。
一,源码
#include "stdafx.h"
#include <windows.h>
//---------------------------------------------------------------------------
typedef struct PictureInfo
{
long left, top; // 起点坐标
long width; // 宽度
long height; // 高度
WORD x_density; // 水平方向密度
WORD y_density; // 垂直方向密度
short colorDepth; // 色深
HLOCAL hInfo; // 图像中的文本信息
} PictureInfo;
//---------------------------------------------------------------------------
typedef int (__stdcall *SPI_GetPluginInfo)(int infono, LPSTR buf, int buflen);
typedef int (__stdcall *SPI_IsSupported)(LPSTR filename, DWORD dw);
typedef int (__stdcall *SPI_GetPictureInfo)(LPSTR buf, long len, unsigned int flag, struct PictureInfo *lpInfo);
typedef int (CALLBACK *SPI_PROGRESS)(int, int, long);
typedef int (__stdcall *SPI_GetPicture)(LPSTR buf, long len, unsigned int flag, HANDLE *pHBInfo, HANDLE *pHBm, SPI_PROGRESS lpPrgressCallback, long lData);
typedef int (__stdcall *SPI_GetPreview)(LPSTR buf, long len, unsigned int flag, HANDLE *pHBInfo, HANDLE *pHBm, FARPROC lpPrgressCallback, long lData);
typedef int (__stdcall *SPI_ConfigurationDlg)(HWND parent, int fnc);
SPI_GetPluginInfo GetPluginInfo;
SPI_IsSupported IsSupported;
SPI_GetPictureInfo GetPictureInfo;
SPI_GetPicture GetPicture;
SPI_GetPreview GetPreview;
SPI_ConfigurationDlg ConfigurationDlg;
HMODULE handle;
//---------------------------------------------------------------------------
bool spi_load(char *spipath)
{
bool ret = false;
handle = LoadLibrary(spipath);
if (NULL != handle)
{
GetPluginInfo = (SPI_GetPluginInfo)GetProcAddress(handle, "GetPluginInfo");
IsSupported = (SPI_IsSupported)GetProcAddress(handle, "IsSupported");
GetPictureInfo = (SPI_GetPictureInfo)GetProcAddress(handle, "GetPictureInfo");
GetPicture = (SPI_GetPicture)GetProcAddress(handle, "GetPicture");
GetPreview = (SPI_GetPreview)GetProcAddress(handle, "GetPreview");
ConfigurationDlg = (SPI_ConfigurationDlg)GetProcAddress(handle, "ConfigurationDlg");
ret = (NULL != IsSupported) & (NULL != GetPictureInfo) & (NULL != GetPicture);
}
return ret;
}
//---------------------------------------------------------------------------
void spi_info(void)
{
const int SPIINFO_SIZE = 256;
char spiinfo[SPIINFO_SIZE];
int ret;
char *mes[] = {"Plug-in API 版本: ", "Plug-in名字、版本和版权:", "文件后缀名:", "文件格式名称:"};
for (int i=0; i < 4; i++)
{
printf(mes[i]);
ret = (*GetPluginInfo)(i, spiinfo, SPIINFO_SIZE);
if (0 != ret)
{
printf(spiinfo);
printf("\n");
}
else
{
printf("NULL\n");
return;
}
}
}
//---------------------------------------------------------------------------
bool spi_check(char *filepath)
{
FILE *fp;
fopen_s(&fp, filepath, "rb");
if (NULL == fp)
{
fprintf(stderr, "文件不能打开。\n");
return false;
}
const int HEADBUF_SIZE = 2000;
char h_buf[HEADBUF_SIZE];
memset(h_buf, 0, HEADBUF_SIZE);
fread(h_buf, 1, HEADBUF_SIZE, fp);
fclose(fp);
char *pdata = h_buf;
int ret = (*IsSupported)(filepath, (DWORD)pdata);
if (0 == ret)
{
fprintf(stderr, "不支持的格式。\n");
return false;
}
return true;
}
//---------------------------------------------------------------------------
bool spi_picinfo(char *filepath)
{
PictureInfo picinfo;
memset(&picinfo, 0, sizeof(picinfo));
int ret = (*GetPictureInfo)(filepath, 0, 0, &picinfo);
if (0 != ret)
{
fprintf(stderr, "GetPictureInfo 错误: %d\n", ret);
return false;
}
printf("left : %d\n", picinfo.left);
printf("top : %d\n", picinfo.top);
printf("width : %d\n", picinfo.width);
printf("height : %d\n", picinfo.height);
printf("x_density : %d\n", picinfo.x_density);
printf("y_density : %d\n", picinfo.y_density);
printf("colorDepth : %d\n", picinfo.colorDepth);
printf("hInfo : ");
if (NULL != picinfo.hInfo)
{
char *pinfo = (char *)GlobalLock(picinfo.hInfo);
printf(pinfo);
GlobalUnlock(picinfo.hInfo);
GlobalFree(picinfo.hInfo);
}
else
{
printf("NULL\n");
}
printf("\n");
return true;
}
//---------------------------------------------------------------------------
bool spi_pic(char *filepath)
{
HANDLE bmpinfo, bmpdata;
int ret = (*GetPicture)(filepath, 0, 0, &bmpinfo, &bmpdata, NULL, 0);
if (0 != ret)
{
fprintf(stderr, "GetPicture 错误:%d\n", ret);
return false;
}
FILE *fp;
fopen_s(&fp, "bmpinfo.bin", "wb");
char *pdata = (char *)LocalLock(bmpinfo);
UINT size = LocalSize(bmpinfo);
fwrite(pdata, 1, size, fp);
LocalUnlock(bmpinfo);
fclose(fp);
fopen_s(&fp, "bmpdata.bin", "wb");
pdata = (char *)LocalLock(bmpdata);
size = LocalSize(bmpdata);
fwrite(pdata, 1, size, fp);
LocalUnlock(bmpdata);
fclose(fp);
LocalFree(bmpinfo);
LocalFree(bmpdata);
return true;
}
//---------------------------------------------------------------------------
bool spi_Prepic(char *filepath)
{
HANDLE bmpinfo, bmpdata;
int ret = (*GetPreview)(filepath, 0, 0, &bmpinfo, &bmpdata, NULL, 0);
if (0 != ret)
{
fprintf(stderr, "GetPreview 错误:%d\n", ret);
return false;
}
FILE *fp;
fopen_s(&fp, "Prebmpinfo.bin", "wb");
char *pdata = (char *)LocalLock(bmpinfo);
UINT size = LocalSize(bmpinfo);
fwrite(pdata, 1, size, fp);
LocalUnlock(bmpinfo);
fclose(fp);
fopen_s(&fp, "Prebmpdata.bin", "wb");
pdata = (char *)LocalLock(bmpdata);
size = LocalSize(bmpdata);
fwrite(pdata, 1, size, fp);
LocalUnlock(bmpdata);
fclose(fp);
LocalFree(bmpinfo);
LocalFree(bmpdata);
return true;
}
//---------------------------------------------------------------------------
bool spi_dlg(int fnc)
{
int ret = (*ConfigurationDlg)(GetConsoleWindow(), fnc);
if (0 != ret)
{
fprintf(stderr, "ConfigurationDlg 错误:%d\n", ret);
return false;
}
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
if (3 > argc)
{
return 0;
}
char *spiname = argv[1];
if (!spi_load(spiname))
{
fprintf(stderr, "spi 文件载入失败。\n");
goto err;
}
char *filename = argv[2];
// 插件信息
spi_info();
// 检查SPI是否支持文件
if (!spi_check(filename))
goto err;
// 取得图片文件的信息
if (!spi_picinfo(filename))
goto err;
// 取得经过SPI处理过的BMP图片数据
if (!spi_pic(filename))
goto err;
// 取得经过SPI处理过的BMP图片数据的预览图,一般都不会有人特别写结构的,多数直接挂接GetPicture
if (!spi_Prepic(filename))
goto err;
// 0 为显示插件的关于窗口,1 为显示设置窗口,2 为以后保留
if (!spi_dlg(0))
goto err;
err:
FreeLibrary(handle);
system("pause");
return 0;
}
二,BMP数据合成
例如,spi_pic 取得的 bmpdata 只是数据部分,bmpinfo 是再前一D的信息,仲差最开头的14位数据。
完整的BMP是:开头的14位数据 + bmpinfo + bmpdata
开头的14位数据:
42 4D E6 E5 00 00 00 00 00 00 36 00 00 00
其中
E6 E5 00 00 = B0 E5 00 00 + 36
原bmpinfo:
28 00 00 00 8C 00 00 00 8C 00 00 00 01 00 18 00 00 00 00 00 B0 E5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
修改为:
28 00 00 00 8C 00 00 00 8C 00 00 00 01 00 18 00 00 00 00 00 B0 E5 00 00 12 0B 00 00 12 0B 00 00 00 00 00 00 00 00 00 00