山西网站建设服务,搭建网站一个服务器和域名,百度人工投诉电话是多少,品牌整合营销方案详解透明贴图和三元光栅操作 - CodeBus
鼠标指针文件格式解析——Windows#xff08;二#xff09; (qq.com)
[C/C] RGBA数组生成Windows下的ico文件_c ico格式-CSDN博客
色环设计 - CodeBus
左键绘制
右键选颜色
ctrl右键设置鼠标热点
F1导出.cur文件 //代码来源二 (qq.com)
[C/C] RGBA数组生成Windows下的ico文件_c ico格式-CSDN博客
色环设计 - CodeBus
左键绘制
右键选颜色
ctrl右键设置鼠标热点
F1导出.cur文件 //代码来源色环https://codebus.cn/luoyh/colorcircle
//代码来源alpha透明贴图 https://codebus.cn/yangw/transparent-putimage//代码来源cur格式https://mp.weixin.qq.com/s?__bizMzkwNzMzMjIyNgmid2247486257idx1sn1656090e498c22f391c00d0857f4b856chksmc0db94dcf7ac1dcacd4618240e05595b984a05b55d5f9f44d277aae41f4353b06bfa5e4294c4cur_album_id2474385342163419137scene189#wechat_redirect
//代码来源icon格式生成文件https://blog.csdn.net/jinzhuojun/article/details/8007586
#include stdio.h
#include graphics.h
#includemath.h
#pragma warning(disable : 4996) // VS2022 对某些函数警告但是为了方便移植就无视这些警告 这样 Devc VC2010 VS2022 都能跑#define PI acos(-1.0)// 鼠标文件解析
//https://mp.weixin.qq.com/s?__bizMzkwNzMzMjIyNgmid2247486257idx1sn1656090e498c22f391c00d0857f4b856chksmc0db94dcf7ac1dcacd4618240e05595b984a05b55d5f9f44d277aae41f4353b06bfa5e4294c4cur_album_id2474385342163419137scene189#wechat_redirect
// 代码来源
//https://blog.csdn.net/jinzhuojun/article/details/8007586
// 中文注释添加自 bilibili 民用级脑的研发记录
// 结构注释来自 https://learn.microsoft.com/en-us/previous-versions/ms997538(vmsdn.10)// 注意这个格式和下文中的 WrietByte 的对应关系//typedef struct
//{
// WORD idReserved; // Reserved (must be 0)
// WORD idType; // Resource Type (1 for icons) // 2 指的是 cur 鼠标静态光标文件
// WORD idCount; // How many images?
// ICONDIRENTRY idEntries[1]; // An entry for each image (idCount of em)
//} ICONDIR, *LPICONDIR;//typedef struct
//{
// BYTE bWidth; // Width, in pixels, of the image
// BYTE bHeight; // Height, in pixels, of the image
// BYTE bColorCount; // Number of colors in image (0 if 8bpp)
// BYTE bReserved; // Reserved ( must be 0)
// WORD wPlanes; // Color Planes
// WORD wBitCount; // Bits per pixel
// DWORD dwBytesInRes; // How many bytes in this resource?
// DWORD dwImageOffset; // Where in the file is this image?
//} ICONDIRENTRY, *LPICONDIRENTRY;
#define _CRT_SECURE_NO_WARNINGS
#include stdio.h
#include stdlib.h
#include string.h
#include assert.h// 色环
void DrawColorCircle(int x, int y, int r, int h)
{int H h;float S 1.f;float V 1.f;for (int i 0; i 360; i){H int(H 1) % 360;setfillcolor(HSVtoRGB((float)H, S, V));solidpie(x - r, y - r, x r, y r, i * (PI / 180), (i 1) * (PI / 180));}
}// 数据写入
void Fwrite(FILE* f, char* data, int byte) // 一次写入 byte 个字节,且只写一次
{if(1!fwrite(data,byte,1,f)){perror(fwrite error);exit(1);}
}
// 数据写入
void WriteByte(FILE* f, unsigned int val,int byte) // 指定写入几个字节
{char data[4];assert(byte4); // 如果它的条件返回错误则终止程序执行——菜鸟教程可查memcpy((void*)data,(void*)val,byte);Fwrite(f,data,byte);
}
// 生成cur 格式文件 ,改写自 icon格式文件的生成仅仅是 wPlane wBitCount 分别作为XY热点
void generate_ico_file(const char* filename,char * body,int width, int height, int has_alpha,int HotX,int HotY)
{int x,y;int index0;int Size0;int offset 6 1*16; // 6 2 2 2这6个byte 是ico,cur通用的文件头。 16 1111 2 2是一个图片的索引占 16 个字节 n个图片的索引占6*16个字节n个图片的因为在不同设备上使用不同型号分辨率的图片这一堆图片都在一个 icon 或cur里int bpp32; // 32位的位图 8位 alpha 8 位 R 8 位 G 8 位 BFILE* outfilefopen(filename,wb);if(outfileNULL){perror(fopen error);exit(1);}// icon文件头类型与图片个数WriteByte(outfile,0,2); // idReserved 保留位一种格式可用区分其他文件。WriteByte(outfile,1,2); // idType 文件类型如果是1 就是icon文件如果是2 则是cur鼠标光标文件这类文件格式一样。WriteByte(outfile,1,2); // idCount 拥有的图片个数icon为在不同屏幕上正常显示会存储多个格式的图片以备选择// 具体一个图片的索引信息WriteByte(outfile,width,1); // bWidthWriteByte(outfile,height,1); // bHeightWriteByte(outfile,0,1); // bColorCountWriteByte(outfile,0,1); // bReserveredWriteByte(outfile,HotX,2); // wPlanes // 这里是.cur热点位置 XWriteByte(outfile,HotY,2); // wBitCount // 这里是.cur热点位置 YSize 40 height * ((width 31) / 32 * 32 / 8 width * 3); //Note 4 bytes alignment // 这里计算文件索引头与图像数据的总数 40444224*6 个字节。 width31/32是计算int 型AND 位图个数width / 32,但是不能确定%32 的部分所以31 然后再除以 32 。1个int 有4个字节共32bit,每个bit表示一个像素是否被光栅操作 AND 覆盖行数 * 32计算一共需要多少bit /8是确定有多少字节。if (bpp 32)Size height * width;WriteByte(outfile,Size, 4); //dwBytesInResWriteByte(outfile,offset, 4); //dwImageOffsetWriteByte(outfile,40, 4); //biSizeWriteByte(outfile,width, 4); //biWidthWriteByte(outfile,2 * height, 4); //biHeightWriteByte(outfile,1, 2); //biPlanesWriteByte(outfile,bpp, 2); //biBitCountWriteByte(outfile,0, 4); //biCompressionWriteByte(outfile,0, 4); //biSizeImageWriteByte(outfile,0, 4); //biXPelsPerMeterWriteByte(outfile,0, 4); //biYPelsPerMeterWriteByte(outfile,0, 4); //biClrUsedWriteByte(outfile,0, 4); //biClrImportant// XOR maskfor (yheight - 1 ; y 0; --y) // 调换打印高度就不会读取了 确定为倒置打印windows倒着读取数据.从左往右从下往上所以为了图片倒着读取之后是正的需要把原图第一行像素数据打印到倒数最后一行{for (x 0; x width; x){index (y * width x) * 4;WriteByte(outfile, body[index], 1); //BlueWriteByte(outfile, body[index 1], 1); //GreenWriteByte(outfile, body[index 2], 1); //RedWriteByte(outfile, has_alpha ? body[index 3] : 255, 1); //Alpha}}// AND maskfor (y 0; y (height * ((width 31) / 32 * 32 / 8)); y){WriteByte(outfile, 1, 1); // 1 在屏幕上显示图片0则不显示图片表示为整个图片没有。 三元光栅操作参考}fclose(outfile);
}int main()
{initgraph(1640, 980, 1);setbkcolor(GREEN);cleardevice();int** mesh;int drawdesklx; // 绘图板左上角坐标int drawdeskly;int pixnum; // 一个正方形瓦片边长像素int mapi; // 一列有多少个小方格int mapj; // 一行有多少个小方格int drawmapi; // 网格坐标int drawmapj;int drawoldmapi; // 同一次绘制的前一个涂色的位置int drawoldmapj;int isdraw; // 绘制状态int drawdeskrx; // 绘图板右下角坐标int drawdeskry;int drawsmallflag;drawsmallflag0;drawdesklx200;drawdeskly200;mapi32; // 默认 64*64 大小的 .cur文件 // 这里改参数只会改写分辨率一个像素对应屏幕一个或多个像素但不会改变图标大小。数值过大会生成失败原因是int数值上限比较小不够存储数据了mapj32; // 这里改参数只会改写分辨率一个像素对应屏幕一个或多个像素但不会改变图标大小。 数值过大会生成失败原因是int数值上限比较小不够存储数据了drawmapi-1;drawmapj-1;pixnum 16 ;drawoldmapi-1;drawoldmapj-1;drawdeskrxdrawdesklxpixnum*mapj; // 瓦片个数 * 一个瓦片的像素 画板总长度drawdeskrydrawdesklypixnum*mapi;int left0; // 刷新绘图板的当前瓦片位置坐标int top0;int pentake0x8FFF0000; // 选中的 ARGB 透明度与颜色int image[mapi * mapj]; // 分配像素内存int i, j;int background 0x0000CCFF; // 背景色天依蓝颜色按十六进制数int HotX0; // 鼠标热点位置int HotY0;mesh new int* [mapi];for(int i0; imapi; i)mesh[i]new int[mapj];for(int i0; imapi; i){for(int j0; jmapj; j){mesh[i][j]0; // 加入默认的背景色}}int h 0;DrawColorCircle(800640 / 4, 480 / 2, 140, h); // 绘制色环setfillcolor(RGB(128, 126, 129));for (int i 0; i mapi ; i){left 0;for (int j 0; j mapj ; j){int pennumber mesh[i][j]; // 读取游戏大地图数组序号//https://codebus.cn/yangw/transparent-putimage
//透明色混合原理与透明色计算代码来源int sa ((pennumber 0xff000000) 24);int sr ((pennumber 0xff0000) 16); // 源值已经乘过了透明系数int sg ((pennumber 0xff00) 8); // 源值已经乘过了透明系数int sb pennumber 0xff; // 源值已经乘过了透明系数int dr ((background 0xff0000) 16);int dg ((background 0xff00) 8);int db background 0xff;int dst ((sr dr * (255 - sa) / 255) 16) // sr 0 dr 255, sa0, dst-red 255,即sa 0 时dr 占优。sr 255 dr0, sa255, dst-red 255, sa255时sr 占优| ((sg dg * (255 - sa) / 255) 8)| (sb db * (255 - sa) / 255);setfillcolor(BGR(dst)); // COLORREF 的颜色格式是 ABGR 需要把 RGB 转换成 BGR 格式然后打印出画板的颜色和保存的图片颜色一样图片按ARGB 保存但是画板按ABGR打印fillrectangle(drawdesklxleft, drawdesklytop, drawdesklxleft pixnum, drawdesklytop pixnum);left pixnum; // 往右移动准备下一次绘制位置,}top pixnum; // 往下移动准备下一次绘制位置}char icon[200]图标预览;setbkmode(TRANSPARENT); // 设置背景为透明settextcolor(BLACK); // 设置字颜色为黑outtextxy(40,160,icon); // 打印提示setfillcolor(GREEN);fillrectangle(10,100,300,140) ; // 覆盖之前的文字提示char tips[200];sprintf(tips,热点位置 HotX HotY %d,%d,HotX,HotY); // 格式化数字setbkmode(TRANSPARENT); // 设置背景为透明settextcolor(BLACK); // 设置字颜色为黑outtextxy(10,100,tips); // 打印提示ExMessage m;while(1){while(peekmessage(m,EX_KEY|EX_MOUSE,1)){switch (m.message){case WM_LBUTTONDOWN:if(m.xdrawdesklxm.ydrawdesklym.xdrawdeskrxm.ydrawdeskry) // 绘制{isdraw1;drawmapi-1;drawmapj-1;}break;case WM_LBUTTONUP:isdraw0;drawoldmapi-1;drawoldmapj-1;drawsmallflag0;break;case WM_RBUTTONDOWN:if(m.xdrawdesklxm.ydrawdesklym.xdrawdeskrxm.ydrawdeskrym.ctrl) // 绘制{HotY(m.y-drawdeskly)/pixnum;HotX(m.x-drawdesklx)/pixnum;setfillcolor(GREEN);fillrectangle(10,100,300,140) ; // 覆盖之前的文字提示char tips[200];sprintf(tips,热点位置 HotX HotY %d,%d,HotX,HotY); // 格式化数字setbkmode(TRANSPARENT); // 设置背景为透明settextcolor(BLACK); // 设置字颜色为黑outtextxy(10,100,tips); // 打印提示}else{pentake getpixel(m.x,m.y);setfillcolor(pentake);fillrectangle(800,500,900,600);pentakepentake|0xFF000000; // 要颜色转换完毕前再补充alpha 通道否则半透明pentakeBGR(pentake); // 因为 getpixel 已经是 BGR了但是在后面的上色还个BGR转换所以还需要再转换一次BGR来抵消后面的BGR转换。// BGR转换是因为保存数据时是 RGB 保存但是当绘制图像时却是蓝色红色相反所以绘制的时候要调整蓝色红色保存的是按RGB来 setfillcolor(GREEN);fillrectangle(800,400,1140,440);char colortips[200];sprintf(colortips,new alpha:%d,red:%d,green:%d,blue:%d,(pentake0xFF000000)24,(pentake0x00FF0000)16,(pentake0x0000FF00)8,(pentake0x000000FF));outtextxy(800,400,colortips); // 打印颜色提示}break;case WM_KEYDOWN:switch (m.vkcode){case VK_F1:int widthmapj;int heightmapi;for (i 0; i height; i){for (j 0; j width; j){image[i * width j] mesh[i][j]; // 透明色 叠加 网格数据} // Alpha 透明 0x00, red: 00, green: 00, blue: 00 各 bit 位对应 ARGB} // 0x00000000是完全透明 0x5F000000 可以看出来不完全透明可知透明度可调节generate_ico_file(testv8_透明度测试.cur, (char *)image, width, height, 1,HotX,HotY);printf(Save cur文件名testv8_透明度测试.cur\n);break;}}}if(isdraw){if(m.xdrawdesklxm.ydrawdesklym.xdrawdeskrxm.ydrawdeskry){drawmapi(m.y-drawdeskly)/pixnum;drawmapj(m.x-drawdesklx)/pixnum;if(drawmapi!drawoldmapi||drawmapj!drawoldmapj) // 检测是否是旧位置{mesh[drawmapi][drawmapj]pentake;drawoldmapidrawmapi;drawoldmapjdrawmapj;drawsmallflag1;}}}if(drawsmallflag1){top0;left0;for (int i 0; i mapi ; i){left 0;for (int j 0; j mapj ; j){int pennumber mesh[i][j]; // 读取游戏大地图数组序号
//https://codebus.cn/yangw/transparent-putimage
//透明色混合原理与透明色计算代码来源int sa ((pennumber 0xff000000) 24);int sr ((pennumber 0xff0000) 16); // 源值已经乘过了透明系数int sg ((pennumber 0xff00) 8); // 源值已经乘过了透明系数int sb pennumber 0xff; // 源值已经乘过了透明系数int dr ((background 0xff0000) 16);int dg ((background 0xff00) 8);int db background 0xff;int dst ((sr dr * (255 - sa) / 255) 16) // sr 0 dr 255, sa0, dst-red 255,即sa 0 时dr 占优。sr 255 dr0, sa255, dst-red 255, sa255时sr 占优| ((sg dg * (255 - sa) / 255) 8)| (sb db * (255 - sa) / 255);setfillcolor(BGR(dst)); // COLORREF 的颜色格式是 ABGR 需要把 RGB 转换成 BGR 格式然后打印出画板的颜色和保存的图片颜色一样图片按ARGB 保存但是画板按ABGR打印fillrectangle(drawdesklxleft, drawdesklytop, drawdesklxleft pixnum, drawdesklytop pixnum);left pixnum; // 往右移动准备下一次绘制位置,}top pixnum; // 往下移动准备下一次绘制位置}top0;for (int i 0; i mapi ; i){left 0;for (int j 0; j mapj ; j){int pennumber mesh[i][j]; // 读取游戏大地图数组序号
//https://codebus.cn/yangw/transparent-putimage
//透明色混合原理与透明色计算代码来源int sa ((pennumber 0xff000000) 24);int sr ((pennumber 0xff0000) 16); // 源值已经乘过了透明系数int sg ((pennumber 0xff00) 8); // 源值已经乘过了透明系数int sb pennumber 0xff; // 源值已经乘过了透明系数int dr ((background 0xff0000) 16);int dg ((background 0xff00) 8);int db background 0xff;int dst ((sr dr * (255 - sa) / 255) 16) // sr 0 dr 255, sa0, dst-red 255,即sa 0 时dr 占优。sr 255 dr0, sa255, dst-red 255, sa255时sr 占优| ((sg dg * (255 - sa) / 255) 8)| (sb db * (255 - sa) / 255);// 绘制预览图putpixel(drawdesklx-64left,drawdeskly-32top,BGR(dst)); // COLORREF 的颜色格式是 ABGR 需要把 RGB 转换成 BGR 格式然后打印出画板的颜色和保存的图片颜色一样图片按ARGB 保存但是画板按ABGR打印left 1; // 往右移动准备下一次绘制位置,}top 1; // 往下移动准备下一次绘制位置}}Sleep(2);}return 0;
}