  |  |   |    |  本帖最后由 群发软件 于 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();  
  
 
 
  |  |    |  |   |  
  |