| | | | 本帖最后由 群发软件 于 2017-6-21 23:31 编辑
1.通过文件的扩展名来判断。这种方法比较简单,但若是有人故意改下文件扩展名,这种方法就不起作用了。 2.通过C#自身提供的方法来进行判断(判断某种确定的图片类型)。 EX: bool isJPG = false; System.Drawing.Image img = System.Drawing.Image.FromFile(filesName); if ( img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg) ) { isJPG = true; } 3.通过读取文件内容来判断。 所有的图片文件都包括:文件识别头和图象数据两部分,其中文件识别头用来让计算机判断是哪种文件 格式。 JPEG 所有的JPEG文件以字符串“0xFFD8”开头,并以字符串“0xFFD9”结束。依此便可判别是否是JPEG文件。 BMP BMP文件以字符串“0x4D42”开头 GIF gif头六个是 GIF89a或 GIF87a c#判断图形文件(GIF,JPG,PNG)的图片格式的方法 #include <windows.h>#include <tchar.h>#include <WindowsX.h>HINSTANCE hInst;#pragma comment(lib,"Msimg32.lib")extern "C"{ extern unsigned char *stbi_load_from_memory(unsigned char const *buffer, int len, int *x, int *y,int *comp, int req_comp); extern void stbi_image_free(void *retval_from_stbi_load);};LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam);int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE,LPTSTR,int nCmdShow){ hInst = hInstance; // Store instance handle in our global variable WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND); wcex.lpszMenuName = NULL; wcex.lpszClassName = _T("std_image.c"); wcex.hIconSm = NULL; if(!RegisterClassEx(&wcex)) return FALSE; HWND hWnd = CreateWindow(_T("std_image.c"), _T("std_image.c"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); DWORD dw = GetLastError(); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); MSG msg; // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam;}LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ switch (message) { case WM_PAINT: { OnPaint(hWnd,wParam,lParam); }break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0;}LRESULT OnPaint(HWND hWnd,WPARAM wParam, LPARAM lParam){ PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); HANDLE hFile = ::CreateFile(_T("test.png"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, \ FILE_ATTRIBUTE_NORMAL, NULL); if( hFile == INVALID_HANDLE_VALUE ) return NULL; DWORD dwSize = ::GetFileSize(hFile, NULL); if( dwSize == 0 ) return NULL; DWORD dwRead = 0; LPBYTE pData = new BYTE[ dwSize ]; ::ReadFile( hFile, pData, dwSize, &dwRead, NULL ); ::CloseHandle( hFile ); if( dwRead != dwSize ) { delete[] pData; return NULL; } LPBYTE pImage = NULL; int x,y,n; pImage = stbi_load_from_memory(pData, dwSize, &x, &y, &n, 4); delete[] pData; if( !pImage ) return NULL; BITMAPINFO bmi; ::ZeroMemory(&bmi, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = x; bmi.bmiHeader.biHeight = -y; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = x * y * 4; bool bAlphaChannel = false; LPBYTE pDest = NULL; HBITMAP hBitmap = ::CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void**)&pDest, NULL, 0); if( !hBitmap ) return NULL;// for( int i = 0; i < x * y; i++ ) // {// pDest[i*4 + 3] = pImage[i*4 + 3];// if( pDest[i*4 + 3] < 255 )//RGBA// {// pDest[i*4] = (BYTE)(DWORD(pImage[i*4 + 2])*pImage[i*4 + 3]/255);// pDest[i*4 + 1] = (BYTE)(DWORD(pImage[i*4 + 1])*pImage[i*4 + 3]/255);// pDest[i*4 + 2] = (BYTE)(DWORD(pImage[i*4])*pImage[i*4 + 3]/255); // bAlphaChannel = true;// }// else // = 255// {// pDest[i*4] = pImage[i*4 + 2];// pDest[i*4 + 1] = pImage[i*4 + 1];// pDest[i*4 + 2] = pImage[i*4]; // }// // if( *(DWORD*)(&pDest[i*4]) == 0 ) {// pDest[i*4] = (BYTE)0;// pDest[i*4 + 1] = (BYTE)0;// pDest[i*4 + 2] = (BYTE)0; // pDest[i*4 + 3] = (BYTE)0;// bAlphaChannel = true;// }// } memcpy(pDest,pImage,bmi.bmiHeader.biSizeImage); stbi_image_free(pImage); HDC hMemdc = CreateCompatibleDC(hdc); SelectBitmap(hMemdc,hBitmap); BLENDFUNCTION ftn = { 0 }; ftn.BlendOp = AC_SRC_OVER; // 目前只能设置这个值 ftn.AlphaFormat = AC_SRC_ALPHA; // 也只能设置这个值 ftn.BlendFlags = 0; // 必须为0 ftn.SourceConstantAlpha = 255; // 指定源图片的alpha AlphaBlend(hdc,0,0,x,y,hMemdc,0,0,x,y,ftn); EndPaint(hWnd, &ps); return 0;}
20121030更正: 上面屏蔽代码不能使用, 以下代码替代 memcpy(pDest,pImage,bmi.bmiHeader.biSizeImage);
因为源码说明 // if you set req_comp to 4, you will always get RGBA output, 所以我应该将其转换成位图的存储格式BGRA, 上次没有发现问题, 原因应该是测试的图片是灰度图片, RGB值是一样的 1.用APIOleLoadPicture来加载JPG、GIF格式的图片(注:不支持PNG格式,另外GIF只能加载第一帧,且不支持透明) OleLoadPicture函数实际上创建了一个IPicture类型的COM接口对象,然后我们可以通过这个COM接口来操作图片(实际上你也可以用APIOleCreatePictureIndirect来加载图片,不过相比而言OleLoadPicture函数简化了基于流的IPicture对象的创建),下面是示例代码:(注:由于只是用来示例,代码中省去了出错情况的处理)
[cpp] view plain copy
print?
- voidDisplayImage(HDC hDC, LPCTSTR szImagePath)
- {
- HANDLE hFile=CreateFile(szImagePath, GENERIC_READ, FILE_SHARE_READ,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);//从指定的路径szImagePath中读取文件句柄
- DWORD dwFileSize=GetFileSize(hFile, NULL);//获得图片文件的大小,用来分配全局内存
- HGLOBAL hImageMemory=GlobalAlloc(GMEM_MOVEABLE, dwFileSize);//给图片分配全局内存
- void *pImageMemory=GlobalLock(hImageMemory); //锁定内存
- DWORD dwReadedSize; //保存实际读取的文件大小
- ReadFile(hFile, pImageMemory, dwFileSize,&dwReadedSize, NULL); //读取图片到全局内存当中
- GlobalUnlock(hImageMemory); //解锁内存
- CloseHandle(hFile); //关闭文件句柄
-
- IStream *pIStream;//创建一个IStream接口指针,用来保存图片流
- IPicture *pIPicture;//创建一个IPicture接口指针,表示图片对象
- CreateStreamOnHGlobal(hImageMemory, false,&pIStream) //用全局内存初使化IStream接口指针
- OleLoadPicture(pIStream, 0, false, IID_IPicture,(LPVOID*)&(pIPicture));//用OleLoadPicture获得IPicture接口指针
-
- //得到IPicture COM接口对象后,你就可以进行获得图片信息、显示图片等操作
- OLE_XSIZE_HIMETRIC hmWidth;
- OLE_YSIZE_HIMETRIC hmHeight;
- pIPicture->get_Width(&hmWidth);//用接口方法获得图片的宽和高
- pIPicture->get_Height(&hmHeight);
- pIPicture->Render(hDC,0,0,100,100,0,hmHeight,hmWidth,-hmHeight,NULL);//在指定的DC上绘出图片
-
- GlobalFree(hImageMemory); //释放全局内存
- pIStream->Release(); //释放pIStream
- pIPicture->Release(); //释放pIPicture
- }
-
2.利用第三方的开发库来操作图片
这 里我向大家推荐一个库CxImage。CxImage里面包含了许多的类,可以用来加载、保存、显示和变换图片,而且支持许多的图片格式,包括BMP、 JPEG、 GIF、PNG、 TIFF、 MNG、 ICO、 PCX、 TGA、 WMF、 WBMP、 JBG、J2K等。另外CxImage也支持Alpha通道,动画帧等许多功能,而且它还是开源免费的。CxImage的当前的版本是v6.00,介绍和下载CxImage的用法十分简单,示例如下(省去出错处理):
[cpp] view plain copy
print?
- voidDisplayImage(HDC hDC, CString fileName)
- {
- CString fileExt; //图片的扩展名
- int len = fileName.GetLength();
- for(int i=len-1; i>=0; i--) //得到图片的扩展名
- {
- if(fileName[ i ] == '.')
- {
- fileExt=fileName.Mid(i+1);
- break;
- }
- }
- fileExt.MakeLower(); //将扩展名转为小写
- if(fileExt != _T(""))
- {
- //创建CxImage对象,其中静态方法CxImage::GetTypeIdFromName用来根据扩展名获得图片格式的ID代表
- CxImage image(fileName,CxImage::GetTypeIdFromName(fileExt));
- if(image.IsValid())
- {
- image.Draw(hDC);
- image.Destroy();
- }
- }
- }
3 提供一中更简单的方法 VC MFC 提供的 API LoadBitmap / LoadImage 类 CBitmap 等都只能操作 BMP位图,图标。对于其他常用的 JPG / JPEG / GIF / PNG 格式,它无能为力。VC 下怎样才能加载各种非 BMP格式的图片呢? 下面介绍一种最简单的办法。用 CImage 类的 Load 函数加载图片,之后用 Detach 取得 HBITMAP句柄。取得图片的HBITMAP 句柄后就可以像操作 BMP 图片一样处理 JPG / JPEG / GIF / PNG格式的图片了。具体代码如下:
[cpp] view plain copy
print?
- #include “atlimage.h”
-
- CImage img;
-
- HRESULT ret = img.Load(filename ); // filename 是要加载的文件名(包含路径)
-
- HBITMAP bitmap = img.Detach();
| | | | |
|