| 
 
 
 
 Легенда:
  новое сообщение 
  закрытая нитка 
  новое сообщение 
  в закрытой нитке 
  старое сообщение   | 
Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
Новичкам также крайне полезно ознакомиться с данным документом.
| [Win32] Как сохранить bmp-файл?  13.10.06 04:48 Автор: Vedrus <Serokhvostov Anton> Статус: Member
 |  
| Люди, кто-нибудь знает, как сохранить картинку в BMP-Файл по-простому? Есть: HANDLE hBitmap и BITMAP bm. Надо сохранить это в bmp-файл. Сохранить картинку "вручную" в принципе возможно, но код сильно разрастается. Возможно ли по простому через API это сделать. Перерыл MSDN - не могу найти |  
|  | Всем спасибо, вопрос исчерпан  23.11.06 15:56 Автор: Vedrus <Serokhvostov Anton> Статус: Member
 |  
|  |  
|  | Gdiplus :-)))  24.10.06 13:40 Автор: Tamas Статус: Member
 Отредактировано 24.10.06 13:51  Количество правок: 4
 |  
| > Люди, кто-нибудь знает, как сохранить картинку в BMP-Файл > по-простому? Есть: HANDLE hBitmap и BITMAP bm. Надо
 > сохранить это в bmp-файл. Сохранить картинку "вручную" в
 > принципе возможно, но код сильно разрастается. Возможно ли
 > по простому через API это сделать. Перерыл MSDN - не могу
 > найти
 
 GDIPLUS :-))) можно сохранить в bmp jpeg tiff png gif.... вот авобще можно просто сохранить в битмап... без всего этого.... вот только придётся разбиратся с заголовком BMP
 
 #include <stdbool.h>
 #include <windows.h>
 
 void *GdiPlusHandle;
 unsigned long GdiplusToken;
 unsigned char *MimeTypeOld;
 
 typedef void(__stdcall*DEBUGEVENTPROC)(void*,char*);
 typedef int(__stdcall*GET_THUMBNAIL_IMAGE_ABORT)(void*);
 
 typedef struct
 {
 unsigned int GdiplusVersion;
 DEBUGEVENTPROC DebugEventCallback;
 int SuppressBackgroundThread;
 int SuppressExternalCodecs;
 }GDIPLUS_STARTUP_INPUT;
 
 GDIPLUS_STARTUP_INPUT GdiplusStartupInput;
 
 typedef struct
 {
 CLSID Clsid;
 GUID  FormatID;
 const unsigned short *CodecName;
 const unsigned short *DllName;
 const unsigned short *FormatDescription;
 const unsigned short *FilenameExtension;
 const unsigned short *MimeType;
 unsigned long Flags;
 unsigned long Version;
 unsigned long SigCount;
 unsigned long SigSize;
 const unsigned char *SigPattern;
 const unsigned char *SigMask;
 }IMAGE_CODAC_INFO;
 
 typedef struct
 {
 GUID Guid;
 unsigned long NumberOfValues;
 unsigned long Type;
 void *Value;
 }ENCODER_PARAMETER;
 
 typedef struct
 {
 unsigned int Count;
 ENCODER_PARAMETER Parameter[1];
 }ENCODER_PARAMETERS;
 
 typedef long(__stdcall*GDIPLUSSTARTUP)(unsigned long*,const GDIPLUS_STARTUP_INPUT*,void*);
 typedef long(__stdcall*GDIPCREATEBITMAPFROMHBITMAP)(void*,void*,void**);
 typedef long(__stdcall*GDIPGETIMAGEENCODERSSIZE)(unsigned int*,unsigned int*);
 typedef long(__stdcall*GDIPGETIMAGEENCODERS)(unsigned int,unsigned int,IMAGE_CODAC_INFO*);
 typedef long(__stdcall*GDIPSAVEIMAGETOFILE)(void*,const unsigned short*,const CLSID*,const ENCODER_PARAMETERS*);
 typedef long(__stdcall*GDIPLODIMAGEFROMSTREAM)(IStream*,void**);
 typedef long(__stdcall*GDIPCREATEHBITMAPFROMBITMAP)(void*,void*,unsigned long);
 typedef long(__stdcall*GDIPDISPOSEIMAGE)(void*);
 typedef long(__stdcall*GDIPGETIMANGETHUMBNAIL)(void*,unsigned int,unsigned int,void,GET_THUMBNAIL_IMAGE_ABORT,void;
 typedef void(__stdcall*GDIPPLUSSHUTDOWN)(unsigned long);
 
 GDIPLUSSTARTUP GdiplusStartup;
 GDIPCREATEBITMAPFROMHBITMAP GdipCreateBitmapFromHBITMAP;
 GDIPGETIMAGEENCODERSSIZE GdipGetImageEncodersSize;
 GDIPGETIMAGEENCODERS GdipGetImageEncoders;
 GDIPSAVEIMAGETOFILE GdipSaveImageToFile;
 GDIPLODIMAGEFROMSTREAM GdipLoadImageFromStream;
 GDIPCREATEHBITMAPFROMBITMAP GdipCreateHBITMAPFromBitmap;
 GDIPDISPOSEIMAGE GdipDisposeImage;
 GDIPGETIMANGETHUMBNAIL GdipGetImageThumbnail;
 GDIPPLUSSHUTDOWN GdiplusShutdown;
 
 bool InitDeinitGdiPlus(bool OnOff)
 {
 static bool InitOK;
 
 if(!OnOff)
 {
 if(GdiplusShutdown!=NULL)GdiplusShutdown(GdiplusToken);
 if(GdiPlusHandle!=NULL)FreeLibrary(GdiPlusHandle);
 InitOK=false;
 GdiplusToken=0;
 return true;
 }
 
 if(InitOK)return true;
 if(!LoadGdiPlusDll())return false;
 
 GdiplusStartupInput.GdiplusVersion=1;
 GdiplusStartupInput.DebugEventCallback=NULL;
 GdiplusStartupInput.SuppressBackgroundThread=false;
 GdiplusStartupInput.SuppressExternalCodecs=false;
 
 if(GdiplusStartup(&GdiplusToken,&GdiplusStartupInput,NULL))
 {
 FreeLibrary(GdiPlusHandle);
 return false;
 }
 
 InitOK=true;
 
 return true;
 }
 
 bool LoadGdiPlusDll(void)
 {
 if(GdiPlusHandle!=NULL)FreeLibrary(GdiPlusHandle);
 
 if((GdiPlusHandle=LoadLibrary("GdiPlus.dll"))==NULL)return false;
 
 if((GdiplusStartup=(GDIPLUSSTARTUP)GetProcAddress(GdiPlusHandle,"GdiplusStartup"))==NULL)
 {
 FreeLibrary(GdiPlusHandle);
 return false;
 }
 
 if((GdipLoadImageFromStream=(GDIPLODIMAGEFROMSTREAM)GetProcAddress(GdiPlusHandle,"GdipLoadImageFromStream"))==NULL)
 {
 FreeLibrary(GdiPlusHandle);
 return false;
 }
 
 if((GdipCreateHBITMAPFromBitmap=(GDIPCREATEHBITMAPFROMBITMAP)GetProcAddress(GdiPlusHandle,"GdipCreateHBITMAPFromBitmap"))==NULL)
 {
 FreeLibrary(GdiPlusHandle);
 return false;
 }
 
 if((GdipCreateBitmapFromHBITMAP=(GDIPCREATEBITMAPFROMHBITMAP)GetProcAddress(GdiPlusHandle,"GdipCreateBitmapFromHBITMAP"))==NULL)
 {
 FreeLibrary(GdiPlusHandle);
 return false;
 }
 
 if((GdipGetImageEncodersSize=(GDIPGETIMAGEENCODERSSIZE)GetProcAddress(GdiPlusHandle,"GdipGetImageEncodersSize"))==NULL)
 {
 FreeLibrary(GdiPlusHandle);
 return false;
 }
 
 if((GdipGetImageEncoders=(GDIPGETIMAGEENCODERS)GetProcAddress(GdiPlusHandle,"GdipGetImageEncoders"))==NULL)
 {
 FreeLibrary(GdiPlusHandle);
 return false;
 }
 
 if((GdipSaveImageToFile=(GDIPSAVEIMAGETOFILE)GetProcAddress(GdiPlusHandle,"GdipSaveImageToFile"))==NULL)
 {
 FreeLibrary(GdiPlusHandle);
 return false;
 }
 
 if((GdipDisposeImage=(GDIPDISPOSEIMAGE)GetProcAddress(GdiPlusHandle,"GdipDisposeImage"))==NULL)
 {
 FreeLibrary(GdiPlusHandle);
 return false;
 }
 
 if((GdipGetImageThumbnail=(GDIPGETIMANGETHUMBNAIL)GetProcAddress(GdiPlusHandle,"GdipGetImageThumbnail"))==NULL)
 {
 FreeLibrary(GdiPlusHandle);
 return false;
 }
 
 if((GdiplusShutdown=(GDIPPLUSSHUTDOWN)GetProcAddress(GdiPlusHandle,"GdiplusShutdown"))==NULL)    {
 FreeLibrary(GdiPlusHandle);
 return false;
 }
 
 return true;
 }
 
 bool GetEnCodacClsid(unsigned char *MimeType,CLSID *Clsid)
 {
 unsigned int NumEncoders;
 unsigned int Size;
 IMAGE_CODAC_INFO *ImageCodecInfo;
 unsigned int CodacIndex;
 unsigned char *RecvMimeType;
 bool OkSearchCodac;
 
 if((MimeType==NULL)||(Clsid==NULL)|GdiPlusHandle==NULL))return false;
 
 ZeroMemory(Clsid,sizeof(*Clsid));
 
 NumEncoders=0;
 Size=0;
 
 if(GdipGetImageEncodersSize(&NumEncoders,&Size))return false;
 
 ImageCodecInfo=LocalAlloc(LPTR,Size);
 
 if(ImageCodecInfo==NULL)return false;
 
 if(GdipGetImageEncoders(NumEncoders,Size,ImageCodecInfo))
 {
 LocalFree(ImageCodecInfo);
 return false;
 }
 
 if(ImageCodecInfo==NULL)
 {
 LocalFree(ImageCodecInfo);
 return false;
 }
 
 RecvMimeType=LocalAlloc(LPTR,Size);
 
 if(RecvMimeType==NULL)
 {
 LocalFree(ImageCodecInfo);
 return false;
 }
 
 OkSearchCodac=false;
 
 for(CodacIndex=0;CodacIndex<NumEncoders;++CodacIndex)
 {
 WideCharToMultiByte(CP_ACP,0,ImageCodecInfo[CodacIndex].MimeType,-1,RecvMimeType,Size,NULL,NULL);
 
 if(strcmp(MimeType,RecvMimeType)==0)
 {
 OkSearchCodac=true;
 break;
 }
 }
 
 if(!OkSearchCodac)
 {
 LocalFree(ImageCodecInfo);
 LocalFree(RecvMimeType);
 return false;
 }
 
 CopyMemory(Clsid,&ImageCodecInfo[CodacIndex].Clsid,sizeof(*Clsid));
 
 LocalFree(ImageCodecInfo);
 LocalFree(RecvMimeType);
 return true;
 }
 
 bool SaveHBitmapToFile(void *HBitmap,unsigned char *FileName,unsigned int Width,unsigned int Height,unsigned char *MimeType,unsigned long JpgQuality)
 {
 void *GBitmap;
 void *GBitmapThumbnail;
 unsigned char *WFileName;
 static CLSID Clsid;
 ENCODER_PARAMETERS EncoderParameters;
 
 if((HBitmap==NULL)||(FileName==NULL)||(MimeType==NULL)|GdiPlusHandle==NULL))return false;
 
 if(MimeTypeOld==NULL)
 {
 if(!GetEnCodacClsid(MimeType,&Clsid))return false;
 MimeTypeOld=LocalAlloc(LPTR,strlen(MimeType)+1);
 if(MimeTypeOld==NULL)return false;
 strcpy(MimeTypeOld,MimeType);
 }
 else
 {
 if(strcmp(MimeTypeOld,MimeType)!=0)
 {
 LocalFree(MimeTypeOld);
 if(!GetEnCodacClsid(MimeType,&Clsid))return false;
 MimeTypeOld=LocalAlloc(LPTR,strlen(MimeType)+1);
 if(MimeTypeOld==NULL)return false;
 strcpy(MimeTypeOld,MimeType);
 }
 }
 
 ZeroMemory(&EncoderParameters,sizeof(EncoderParameters));
 EncoderParameters.Count=1;
 EncoderParameters.Parameter[0].Guid.Data1=0x1d5be4b5;
 EncoderParameters.Parameter[0].Guid.Data2=0xfa4a;
 EncoderParameters.Parameter[0].Guid.Data3=0x452d;
 EncoderParameters.Parameter[0].Guid.Data4[0]=0x9c;
 EncoderParameters.Parameter[0].Guid.Data4[1]=0xdd;
 EncoderParameters.Parameter[0].Guid.Data4[2]=0x5d;
 EncoderParameters.Parameter[0].Guid.Data4[3]=0xb3;
 EncoderParameters.Parameter[0].Guid.Data4[4]=0x51;
 EncoderParameters.Parameter[0].Guid.Data4[5]=0x05;
 EncoderParameters.Parameter[0].Guid.Data4[6]=0xe7;
 EncoderParameters.Parameter[0].Guid.Data4[7]=0xeb;
 EncoderParameters.Parameter[0].NumberOfValues=1;
 EncoderParameters.Parameter[0].Type=4;
 EncoderParameters.Parameter[0].Value=(void*)&JpgQuality;
 
 GBitmap=NULL;
 
 if(GdipCreateBitmapFromHBITMAP(HBitmap,NULL,&GBitmap))return false;
 
 WFileName=LocalAlloc(LPTR,(strlen(FileName)*sizeof(unsigned short))+1);
 if(WFileName==NULL)return false;
 
 MultiByteToWideChar(CP_ACP,0,FileName,-1,WFileName,(strlen(FileName)*sizeof(unsigned short))-1);
 
 if((Width>0)&&(Height>0))
 {
 GBitmapThumbnail=NULL;
 
 if(GdipGetImageThumbnail(GBitmap,Width,Height,&GBitmapThumbnail,NULL,NULL))
 {
 GdipDisposeImage(GBitmap);
 LocalFree(WFileName);
 return false;
 }
 
 GdipDisposeImage(GBitmap);
 GBitmap=GBitmapThumbnail;
 }
 
 if(GdipSaveImageToFile(GBitmap,WFileName,&Clsid,&EncoderParameters))
 {
 GdipDisposeImage(GBitmap);
 LocalFree(WFileName);
 return false;
 }
 
 GdipDisposeImage(GBitmap);
 LocalFree(WFileName);
 return true;
 }
 |  
|  | ATL'овский класс CImage. Причем работает не только с bmp.  14.10.06 13:48 Автор: makeworld Статус: Member
 |  
|  |  
|  |  | Спасибо за внимание, но я и сам написал подобный код. Нет ли...  13.10.06 15:07 Автор: Vedrus <Serokhvostov Anton> Статус: Member
 |  
| Спасибо за внимание, но я и сам написал подобный код. Нет ли вариантов проще? Буду сильно благодарен |  
|  |  |  | Проще можно через GDIplus  13.10.06 22:55 Автор: Neznaika <Alex> Статус: Member
 |  
| Эта библиотека устанавливается вместе с Windows XP или выше. |  
 
 
 |  |