请使用C语言,写出一个使用Windows自带函数的,能够导入外部图片的代码,并且有注释
时间: 2024-03-18 17:41:35 浏览: 47
好的,以下是一个使用C语言和Windows自带函数的示例代码,可以导入外部图片:
```c
#include <windows.h>
#include <wingdi.h>
int main()
{
// 打开文件对话框,选择图片文件
OPENFILENAME ofn;
char szFileName[MAX_PATH] = { 0 };
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = "Image Files (*.bmp;*.jpg;*.png)\0*.bmp;*.jpg;*.png\0All Files (*.*)\0*.*\0";
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.lpstrDefExt = "";
if (GetOpenFileName(&ofn))
{
// 打开图片文件,读取数据
HANDLE hFile = CreateFile(ofn.lpstrFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
DWORD dwFileSize = GetFileSize(hFile, NULL);
BYTE* pbFileData = (BYTE*)malloc(dwFileSize);
DWORD dwBytesRead = 0;
ReadFile(hFile, pbFileData, dwFileSize, &dwBytesRead, NULL);
// 创建位图
BITMAPINFO bmpInfo;
ZeroMemory(&bmpInfo, sizeof(bmpInfo));
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = 0; // 宽度和高度为0时,CreateDIBSection会根据文件数据自动计算
bmpInfo.bmiHeader.biHeight = 0;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 0;
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biSizeImage = 0;
bmpInfo.bmiHeader.biXPelsPerMeter = 0;
bmpInfo.bmiHeader.biYPelsPerMeter = 0;
bmpInfo.bmiHeader.biClrUsed = 0;
bmpInfo.bmiHeader.biClrImportant = 0;
BITMAPINFOHEADER* pHeader = &bmpInfo.bmiHeader;
if (pbFileData[0] == 'B' && pbFileData[1] == 'M')
{
// bmp格式
pHeader = (BITMAPINFOHEADER*)(pbFileData + 14);
}
else if (pbFileData[0] == 0xFF && pbFileData[1] == 0xD8)
{
// jpg格式
BYTE* pStart = pbFileData;
BYTE* pEnd = pbFileData + dwFileSize;
while (pStart < pEnd)
{
if (pStart[0] == 0xFF && pStart[1] == 0xC0)
{
pHeader = (BITMAPINFOHEADER*)(pStart + 2);
break;
}
pStart++;
}
}
else if (pbFileData[0] == 0x89 && pbFileData[1] == 'P' && pbFileData[2] == 'N' && pbFileData[3] == 'G')
{
// png格式
pHeader = (BITMAPINFOHEADER*)(pbFileData + 16);
}
// 创建设备无关位图
HDC hdc = GetDC(NULL);
HBITMAP hBitmap = CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, NULL, NULL, 0);
ReleaseDC(NULL, hdc);
// 复制数据到位图
BYTE* pBits = NULL;
HDC hMemDC = CreateCompatibleDC(NULL);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
SetDIBits(hMemDC, hBitmap, 0, pHeader->biHeight, pbFileData + pHeader->biSize, &bmpInfo, DIB_RGB_COLORS);
// 保存位图为文件
HANDLE hFileOut = CreateFile("output.bmp", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFileOut != INVALID_HANDLE_VALUE)
{
BITMAPFILEHEADER fileHeader;
ZeroMemory(&fileHeader, sizeof(fileHeader));
fileHeader.bfType = 0x4D42;
fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + pHeader->biSizeImage;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
DWORD dwBytesWritten = 0;
WriteFile(hFileOut, &fileHeader, sizeof(fileHeader), &dwBytesWritten, NULL);
WriteFile(hFileOut, pHeader, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
WriteFile(hFileOut, pbFileData + pHeader->biSize, pHeader->biSizeImage, &dwBytesWritten, NULL);
CloseHandle(hFileOut);
}
// 释放资源
SelectObject(hMemDC, hOldBitmap);
DeleteDC(hMemDC);
free(pbFileData);
DeleteObject(hBitmap);
}
CloseHandle(hFile);
}
return 0;
}
```
以上代码通过Windows自带的GetOpenFileName函数打开文件对话框,选择图片文件,然后使用CreateFile函数打开图片文件,读取数据。接着创建位图,根据文件数据自动计算宽度和高度,使用CreateDIBSection函数创建设备无关位图,并将数据复制到位图中。最后将位图保存为文件,释放资源。需要注意的是,以上代码只支持bmp、jpg和png格式的图片。
阅读全文