.icon 24 位位图读取

代码来源

读取格式来自:Icons | Microsoft Learn

rgb打印来自:位图(BMP)文件结构分析以及使用C++实现位图的读写与显示 - 简书 (jianshu.com)

位图转 icon 文件网站:

 w​​​​​​​在线生成透明ICO图标 - 在线工具 (toollist.net)

 

​​​​​​​Dev-C++ undefined reference to `_imp_SetPixel` 解决方法_为什么找不到标识符setpixel怎么解决-CSDN博客

#include <stdio.h>
#include <windows.h>
#pragma warning(disable : 4996)					// visual studio 宏定义,避免移植到Visual studio编译报错 

// 核心代码自 
//https://learn.microsoft.com/en-us/previous-versions/ms997538(v=msdn.10)


//掩码图,其中有 XOR AND 俩图片,都是用一个bit 0表示黑,1表示白,即一个字节对应八个像素
typedef struct
{
	BITMAPINFOHEADER   icHeader;      // DIB header
	RGBQUAD         icColors[1];   // Color table
	BYTE            icXOR[1];      // DIB bits for XOR mask
	BYTE            icAND[1];      // DIB bits for AND mask
} ICONIMAGE, *LPICONIMAGE;
// 一个ICON 文件有多个图片,是因为不同机器上识别不同格式图片,这里是紧随ICON文件头之后的图片信息结构体
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;


// ICON 文件头
typedef struct
{
	WORD           idReserved;   // Reserved (must be 0)
	WORD           idType;       // Resource Type (1 for icons)
	WORD           idCount;      // How many images?
	ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
} ICONDIR, *LPICONDIR;


// 用于显示 Icon 的全部结构体数据 ,如果正常显示,说明微软的代码靠谱 
void showIcon(LPICONDIR pIconDir,LPICONDIRENTRY pIconDirEntry,LPICONIMAGE pIconImage)
{
	printf("pIconDir\n");
	printf("%0x\n",pIconDir->idReserved);
	printf("%0x\n",pIconDir->idType);
	printf("%0x\n",pIconDir->idCount);

	printf("pIconDirEntry\n");
	printf("bHeight = %d\n",pIconDirEntry->bHeight);
	printf("bWidth = %d\n",pIconDirEntry->bWidth);
	printf("%0x\n",pIconDirEntry->bColorCount);
	printf("%0x\n",pIconDirEntry->bReserved);
	printf("%0x\n",pIconDirEntry->wPlanes);
	printf("%0x\n",pIconDirEntry->wBitCount);
	printf("%ld\n",pIconDirEntry->dwBytesInRes);
	printf("%ld\n",pIconDirEntry->dwImageOffset);

	printf("pIconImage->icHeader\n");
//	https://zhuanlan.zhihu.com/p/339055549
//	https://blog.csdn.net/wangwenjing90/article/details/8537355
//	https://blog.csdn.net/weixin_44350503/article/details/90082061
	printf("%ld\n",pIconImage->icHeader.biSize);					// biSize = BMP头的info头部分的文件大小(以字节为单位)
//	icHeader 结构的 biHeight 成员表示 XOR 和 AND 掩码的组合高度。
	printf("icHeader.biHeight = %ld\n",pIconImage->icHeader.biHeight);
	printf("icHeader.biWidth =  %ld\n",pIconImage->icHeader.biWidth);

	printf("%d\n",pIconImage->icHeader.biPlanes);					// biPlanes 颜色平面数 https://blog.csdn.net/mmxida/article/details/122362449#:~:text=%E5%9C%A8%E4%B8%80%E4%B8%AA%E9%BB%98%E8%AE%A4%E7%9A%8416%E8%89%B2%E7%9A%84%E8%B0%83%E8%89%B2%E6%9D%BF%E4%B8%AD%EF%BC%8C%E9%A2%9C%E8%89%B2%E8%A2%AB%E7%B3%BB%E7%BB%9F%E6%8C%89%E7%85%A7%E4%B8%80%E5%AE%9A%E7%9A%84%E8%A7%84%E5%88%99%E8%BF%9B%E8%A1%8C%E5%88%86%E9%85%8D%EF%BC%8C%E4%BE%8B%E5%A6%82%E4%BD%8D0%E8%A1%A8%E7%A4%BA%E8%93%9D%E8%89%B2%E9%80%9A%E9%81%93%EF%BC%8C%E4%BD%8D1%E8%A1%A8%E7%A4%BA%E7%BB%BF%E8%89%B2%E9%80%9A%E9%81%93%EF%BC%8C%E4%BD%8D2%E8%A1%A8%E7%A4%BA%E7%BA%A2%E8%89%B2%E9%80%9A%E9%81%93%EF%BC%8C%E4%BD%8D4%E8%A1%A8%E7%A4%BA%E5%BC%BA%E5%BA%A6%E9%80%9A%E9%81%93%E3%80%82%20%E6%A0%B9%E6%8D%AE%E8%BF%99%E4%B8%AA%E8%A7%84%E5%88%99%EF%BC%8C%E8%BF%994%E4%B8%AA%E4%BD%8D%E5%8F%AF%E4%BB%A5%E8%A2%AB%E8%A7%A3%E9%87%8A%E4%B8%BA%EF%BC%9A%E5%BC%BA%E5%BA%A6%E5%B9%B3%E9%9D%A2%EF%BC%8C%E7%BA%A2%E8%89%B2%E5%B9%B3%E9%9D%A2%EF%BC%8C%E7%BB%BF%E8%89%B2%E5%B9%B3%E9%9D%A2%E5%92%8C%E8%93%9D%E8%89%B2%E5%B9%B3%E9%9D%A2%E3%80%82%20%E5%AF%B9%E4%BA%8E%E6%9C%80%E5%90%8E%E4%B8%89%E4%B8%AA%E5%B9%B3%E9%9D%A2%EF%BC%8C%E6%82%A8%E5%8F%AF%E4%BB%A5%E6%83%B3%E8%B1%A1%E6%AF%8F%E4%B8%AA%E5%B9%B3%E9%9D%A2%E9%83%BD%E4%BB%A3%E8%A1%A8%E4%BA%86%E5%A6%82%E6%9E%9C%E5%8F%AA%E6%9C%89%E7%9B%B8%E5%BA%94%E7%9A%84%E7%94%B5%E5%AD%90%E6%9E%AA%E5%9C%A8%E5%8F%91%E5%B0%84%E6%97%B6%E4%BD%A0%E7%9C%8B%E5%88%B0%E7%9A%84%E6%83%85%E5%86%B5%E3%80%82%20%E7%94%B1%E4%BA%8E%E8%BF%99%E6%98%AFEGA%E7%9A%84%E6%9C%AC%E6%9C%BA%E9%A2%9C%E8%89%B2%E6%A0%BC%E5%BC%8F%EF%BC%8C%E5%9B%A0%E6%AD%A4%E9%9C%80%E8%A6%81%E6%9C%89%E4%B8%80%E7%A7%8D%E6%96%B9%E6%B3%95%E5%9C%A8BITMAP%E7%BB%93%E6%9E%84%E4%B8%AD%E8%A1%A8%E8%BE%BE%E8%BF%99%E7%A7%8D%E9%A2%9C%E8%89%B2%E6%A0%BC%E5%BC%8F%EF%BC%8C%E4%BB%A5%E4%BE%BF,Windows%E5%8F%AF%E4%BB%A5%E8%A1%A8%E7%A4%BA%E4%B8%8E%E8%AE%BE%E5%A4%87%E7%9B%B8%E5%85%B3%E7%9A%84%E4%BD%8D%E5%9B%BE%E3%80%82%20%E5%9B%A0%E6%AD%A4%E8%AF%9E%E7%94%9F%E4%BA%86%E5%B9%B3%E9%9D%A2%E9%A2%9C%E8%89%B2%E6%A0%BC%E5%BC%8F%E3%80%82%20%E5%AF%B9%E4%BA%8E16%E8%89%B2%E5%B9%B3%E9%9D%A2%E7%9A%84%E4%BD%8D%E5%9B%BE%EF%BC%8C%E5%B9%B3%E9%9D%A2%E6%95%B0%E4%B8%BA%204%EF%BC%8C%E6%AF%8F%E4%B8%AA%E5%83%8F%E7%B4%A0%E7%9A%84%E4%BD%8D%E6%95%B0%E4%B8%BA%201%E3%80%82
	printf("%d\n",pIconImage->icHeader.biBitCount);					// biBitCount 每个像素的位数 图像位深度:1,4,8,16,24,32
	printf("%ld\n",pIconImage->icHeader.biCompression);				// biCompression 图像数据压缩类型:0(BI_RGB,不压缩),1(BI_RLE8,8比特游程编码),2(BI_RLE4,4比特游程编码),3(BI_BITFIELDS,比特域),4(BI_JPEG),5(BI_PNG)
	printf("%ld\n",pIconImage->icHeader.biSizeImage);				// biSizeImage 图像大小,用BI_RGB格式时,可设置为0.

//	https://blog.csdn.net/wangwenjing90/article/details/8537355
	printf("%ld\n",pIconImage->icHeader.biXPelsPerMeter);			// biXPelsPerMeter 水平分辨率,用于多图片存进 ICON时,在不同设备上像素密集程度不同,用于选取密集程度较接近当前设备的图片 ,但是一般不用管。
	printf("%ld\n",pIconImage->icHeader.biYPelsPerMeter);			// biYpelxPerMeter 垂直分辨率
	printf("%ld\n",pIconImage->icHeader.biClrUsed); 				// biCLrUsed 颜色索引数,查颜色表 https://blog.csdn.net/OrdinaryMatthew/article/details/114644916
	printf("%ld\n",pIconImage->icHeader.biClrImportant);			// biClrImortant 对图像显示有重要影响的颜色索引数,0表示都重要
	
	// 文件最顶上的微软教程链接中解释 is Colors 对应颜色表,因为 icHeader的 颜色索引不用了,isColors 成为了索引 
	printf("pIconImage->icColors[0]\n");							// icColors 成员是 RGBQUAD 的数组。此数组中的元素数是通过检查 icHeader 成员来确定的。
	printf("%d\n",pIconImage->icColors[0].rgbRed);
	printf("%d\n",pIconImage->icColors[0].rgbGreen);
	printf("%d\n",pIconImage->icColors[0].rgbBlue); 
	printf("%d\n",pIconImage->icColors[0].rgbReserved);
	

	printf("\n"); 
}
// 按名称复刻,发现isColor就是当前的像素数据
//代码来源  https://www.jianshu.com/p/1e4f302f43d0 
 void showBitmap(LPICONIMAGE pIconImage) {
    HWND hWindow;                                                //窗口句柄
    HDC hDc;                                                     //绘图设备环境句柄
    int yOffset = 150;                      
    hWindow = GetForegroundWindow();
    hDc = GetDC(hWindow);

    int posX, posY;
    for (int i = 0; i < pIconImage->icHeader.biWidth*pIconImage->icHeader.biHeight/2; i++){				// 除以二是因为 biHeight 计算的是掩码图 和色彩图的总数 
        char blue = pIconImage->icColors[i].rgbBlue;				// 读取一个字节的数据 刚好 char 就是一个字节,里面的 0 1 变成 0-255 
        char green = pIconImage->icColors[i].rgbGreen;
        char red = pIconImage->icColors[i].rgbRed;

        posX = i % pIconImage->icHeader.biWidth;
        posY = pIconImage->icHeader.biHeight - i / pIconImage->icHeader.biWidth + yOffset;
        SetPixel(hDc, posX, posY, RGB(red, green, blue));
    } 
    
  
}
int main()
{
	LPICONDIR pIconDir;							// 用于记录一个完整的ICON 数据头
//	https://blog.csdn.net/jeanphorn/article/details/44982273
	HANDLE hFile=  CreateFile("22.ico",GENERIC_READ,
	                          FILE_SHARE_READ,
	                          NULL,
	                          OPEN_EXISTING,        //打开已存在的文件
	                          FILE_ATTRIBUTE_NORMAL,
	                          NULL);
	DWORD dwBytesRead;								// 要读取的字节数,DROWD 就是 unsigned _long32 ctrl+鼠标左键可查
	// We need an ICONDIR to hold the data
	pIconDir = (LPICONDIR)malloc( sizeof( ICONDIR ) );
// Read the Reserved word
	dwBytesRead=1;
	ReadFile( hFile, &(pIconDir->idReserved), sizeof( WORD ), &dwBytesRead, NULL );
// Read the Type word - make sure it is 1 for icons
	dwBytesRead=1;
	ReadFile( hFile, &(pIconDir->idType), sizeof( WORD ), &dwBytesRead, NULL );
// Read the count - how many images in this file?
	dwBytesRead=1;						// deByteRead=1 是指读的 1个 WORD ,就是读取一个字,这里对应读取两个字节因为unsigned short是两个字节
	ReadFile( hFile, &(pIconDir->idCount), sizeof( WORD ), &dwBytesRead, NULL );
// Reallocate IconDir so that idEntries has enough room for idCount elements
	pIconDir = (LPICONDIR)realloc( pIconDir, ( sizeof( WORD ) * 3 ) +
	                               ( sizeof( ICONDIRENTRY ) * pIconDir->idCount ) );
// Read the ICONDIRENTRY elements
	ReadFile( hFile, pIconDir->idEntries, pIconDir->idCount * sizeof(ICONDIRENTRY),
	          &dwBytesRead, NULL );
// Loop through and read in each image
	int i;
	LPICONIMAGE pIconImage;
	for(i=0; i<pIconDir->idCount; i++)
	{
		// Allocate memory to hold the image
		pIconImage =(LPICONIMAGE) malloc( pIconDir->idEntries[i].dwBytesInRes );
		// Seek to the location in the file that has the image
		SetFilePointer( hFile, pIconDir->idEntries[i].dwImageOffset,
		                NULL, FILE_BEGIN );
		// Read the image data
		dwBytesRead=1; // 字节数已经在 dwBytesInRes 中给出了,所以 dwBytesRead 成为 1就是 只读取一次 
		ReadFile( hFile, pIconImage, pIconDir->idEntries[i].dwBytesInRes,
		          &dwBytesRead, NULL );
		// Here, pIconImage is an ICONIMAGE structure. Party on it :)

		//显示读取的数据信息
		showIcon(pIconDir,&pIconDir->idEntries[i],pIconImage);
		// Then, free the associated memory
		
		showBitmap(pIconImage); 
		
		Sleep(3000); 
		
		free( pIconImage );
	}
// Clean up the ICONDIR memory
	free( pIconDir );
	return 0; 
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/536855.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++调用python脚本

1、在属性页配置 包含目录和库目 2、引入头文件并实现代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 // ConsoleApplication22.cpp : 此文件包含 &…

2024年第十四届 Mathorcup (B题)| 甲骨文智能识别 | 深度学习 计算机视觉 |数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 让我们来看看Mathorcup (B题&#xff09;&#xff01; CS团队…

AI预测福彩3D第33弹【2024年4月12日预测--第8套算法开始计算第1次测试】

今天在出预测结果之前&#xff0c;咱们先做一下经验总结。经过前面第7套算法8次的测试&#xff0c;发现了一些非常稳定的规律&#xff0c;这些规律可以作为杀号的条件&#xff1b;另一方面&#xff0c;存在一些冲突矛盾的规律&#xff0c;一旦使用&#xff0c;就可能会把中奖号…

【前缀合】Leetcode 和为k的子数组

题目解析 560. 和为 K 的子数组 算法讲解 前面滑动窗口里面有一道题和这个题很相似&#xff0c;它是求出和为k的最短子数组的长度&#xff0c;但是这道题不能使用滑动窗口&#xff0c;因为虽然找到一段子数组的和等于k&#xff0c;但是这道题里面存在0和负数&#xff0c;可能…

英伟达旗下AI估值暴增?!!

在AI初创领域中&#xff0c;OpenAI和Anthropic两家获得融资最多的闭源大模型公司备受瞩目&#xff0c;它们的投资背后分别是实力雄厚的微软和亚马逊。 资本巨头进军AI领域&#xff0c;所投入的不仅仅是资金&#xff0c;更是宝贵的云计算资源。这种全力支持的做法&#xff0c;无…

路线选择 | 用ZStack Cloud替代升级VMware

2024年&#xff0c;被博通收购后的VMware全面走向订阅模式&#xff0c;VMware将各产品线改为以VVEP/VVS/VVF/VCF四大基础订阅包并叠加组件的模式进订阅制服&#xff0c;从永久授权改为1/3/5年订阅&#xff0c;且订阅制后售卖规则也进行了调整。 对于用户来讲&#xff0c;VMwar…

C语言 函数——代码风格

目录 基本的代码规范 程序版式 对齐&#xff08;Alignment&#xff09;与缩进&#xff08;indent&#xff09; 变量的对齐规则 空行——分隔程序段落的作用 代码行内的空格——增强单行清晰度 代码行 长行拆分 标识符命名规则 标识符命名的共性规则 windows应用程序…

SpringBoot启动时banner设置

SpringBoot启动时banner设置 1.操作步骤2.各种banner图像 1.操作步骤 在application.properties文件中设置新的banner对于的文件位置&#xff0c;最好放在resources目录下 spring.banner.locationbanner.txt2.各种banner图像 &#xff08;1&#xff09;经典大佛图 具体txt文…

Docker学习笔记(一):入门篇,Docker概述、基本组成等,对Docker有一个初步的认识

前言 记录时间 [2024-4-5] 在先前的文章中&#xff0c;笔者进行了Windows系统下YOLOv8模型的简单测试&#xff0c;并由此引发思考&#xff1a;是否能尝试将此模型运行在Linux中呢&#xff1f;又或者&#xff0c;运行在Docker中。关于Docker的学习就这么展开了。 本文便是有关D…

车载视频智能创作解决方案,影视级视频制作

当下车载视频已经不仅仅是一种记录行车过程的方式&#xff0c;更是展现企业品牌形象、传递文化内涵的重要媒介。传统的车载视频制作方式往往耗时耗力&#xff0c;效率低下&#xff0c;无法满足企业对于高质量、高效率的需求。针对这一痛点&#xff0c;美摄科技凭借其在视频智能…

算法 分割字符串为实体类

题目 String userData "10000:张三:男:1998-01-01#10001:张三:男:1998-01-01#10002:李四:女:1999-02-02#10003:王五:男:2000-03-03#10004:赵六:女:2001-04-04"; String[] usersArray userData.split("#"); // 使用Stream API将字符串数组转换为SysUser对…

SpringBoot学习之Kibana下载安装和启动(三十二)

一、简介 Kibana是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使用的。你可以用kibana搜索、查看存放在Elasticsearch中的数据。Kibana与Elasticsearch的交互方式是各种不同的图表、表格、地图等,直观的展示数据,从而达到高级的数据分析与可视化的目的。 …

新版网络安全等级保护定级指南解读

网络安全等级保护工作的作用对象&#xff0c;主要包括基础信息网络、工业控制系统、云计算平台、物联网、使用移动互联技术的网络和大数据等。 软件开发全套资料获取进主页或者本文末个人名片直接获取。

【应急响应事件】记一次矿机木马事件

事情起因&#xff0c;是因为实验室有一台服务器的占用率从开机启动就是100%&#xff0c;很怀疑就是中了某种矿机木马&#xff0c;拿去挖矿了&#xff0c;然后经过师兄的不懈努力&#xff0c;终于找到了木马文件&#xff0c;给他命名为virus_sample 然后我就拿着样本去逆了 木马…

前端React笔记(尚硅谷)

react 尚硅谷react教程 jsx语法规则 1.定义虚拟dom时不加引号&#xff08;不是字符串&#xff09; 2.标签中混入js表达式时要用{} js表达式与js语句不同。 js语句是if&#xff08;&#xff09;&#xff0c;for&#xff08;&#xff09;&#xff0c;switch&#xff08;&#x…

Python生成图片和音频验证码

captcha是pyhton的一个模块&#xff0c;用来生成图片和音频验证码。 安装 pip install captcha使用 from captcha.audio import AudioCaptcha from captcha.image import ImageCaptcha# 加载声音和字体 audio AudioCaptcha(voicedir/path/to/voices) image ImageCaptcha(…

Linux的环境搭建

目录 第一步&#xff1a;购买腾讯云轻量级云服务器 Step1&#xff1a;打开腾讯云 ​编辑 Step2&#xff1a;登录腾讯云并完成认证 Step3&#xff1a;选择服务器类型 Step4&#xff1a;选择服务器配置 第二部&#xff1a;下载XShell Step1&#xff1a;打开XShell Step2…

亚马逊云科技云从业者考证自习室招生啦!

今天小李哥安利的是亚马逊云科技国内社区User Group(UG)的最新线上活动&#xff0c;云从业者考证自习室(图1)。该活动将由亚马逊云科技社区技术大牛、考证大牛们&#xff0c;帮助大家在一个月内陪伴式学习、保姆级教学、提供免费备考课程&#xff0c;帮助大家在短短一个月内稳稳…

tensorflow.js 如何从 public 路径加载人脸特征点检测模型

系列文章目录 如何在前端项目中使用opencv.js | opencv.js入门如何使用tensorflow.js实现面部特征点检测tensorflow.js 如何从 public 路径加载人脸特征点检测模型tensorflow.js 如何使用opencv.js通过面部特征点估算脸部姿态并绘制示意图tensorflow.js 使用 opencv.js 将人脸…

ArcGIS Pro中的3D建模

在本文中,我讲述了我最近一直在探索的在 ArcGIS Pro 中设计 3D 模型的过程。 我的目标是尽可能避免与其他软件交互(即使是专门用于 3D 建模的软件),并利用 Pro 可以提供的可能性。 这个短暂的旅程分为三个不同的阶段:准备、组装和照明。 我们必须使用一些布局可能性以及一…