Y_Mur Заметил значение Вашего GUID'а только после того, как написал свой пример. GUID энкодера и GUID формата - это вроде как не одно и то же. Огромное преимущество GDI+ в том, что достаточно всего лишь заменить GUID и получите любой поддерживаемый формат. А геморрой с заголовками - одноразовый, причем BMP - это простейший случай. Вот пример на фасме для BMP: Код (Text): format PE GUI 4.0 include 'win32a.inc' struct GdiplusStartupInput GdiplusVersion dd ? DebugEventCallback dd ? SuppressBackgroundThread dd ? SuppressExternalCodecs dd ? ends struct EncoderParameter GUID dd 4 dup ? NumberOfValues dd ? Type dd ? Value dd ? ends struct EncoderParameters Count dd ? Parameter EncoderParameter <> ends main: invoke GetWindowDC,0 mov dword[DesktopDC],eax invoke GetSystemMetrics,SM_CXSCREEN mov esi,eax ;esi - screen width invoke GetSystemMetrics,SM_CYSCREEN mov edi,eax ;edi - screen height invoke CreateCompatibleBitmap,[DesktopDC],esi,edi mov dword[hDeskBMP],eax invoke CreateCompatibleDC,[DesktopDC] mov dword[dcDeskBMP],eax invoke SelectObject,[dcDeskBMP],[hDeskBMP] mov dword[hPrevObject],eax invoke BitBlt,[dcDeskBMP],0,0,esi,edi,[DesktopDC],0,0,SRCCOPY mov dword[tSI.GdiplusVersion],1 invoke GdiplusStartup,tGDIP,tSI invoke GdipCreateBitmapFromHBITMAP,[hDeskBMP],0,frDesktopBitmap invoke GdipSaveImageToFile,[frDesktopBitmap],fPath,GUIDImageEncoderBMP,NULL invoke GdipDisposeImage,[frDesktopBitmap] invoke GdiplusShutdown,[tGDIP] invoke DeleteDC,[dcDeskBMP] invoke DeleteObject,[hDeskBMP] invoke ReleaseDC,0,[DesktopDC] invoke ExitProcess,0 fPath du 'C:\Bitmap.bmp',0 GUIDImageEncoderBMP: dd 557CF400h dw 1A04h,11D3h db 09Ah,073h,000h,000h,0F8h,01Eh,0F3h,02Eh data import library kernel32,'kernel32.dll',\ user32,'user32.dll',\ gdi32,'gdi32.dll',\ gdiplus,'gdiplus.dll' import kernel32,\ CloseHandle,'CloseHandle',\ ExitProcess,'ExitProcess' import user32,\ GetWindowDC,'GetWindowDC',\ ReleaseDC,'ReleaseDC',\ GetSystemMetrics,'GetSystemMetrics' import gdi32,\ CreateCompatibleDC,'CreateCompatibleDC',\ DeleteDC,'DeleteDC',\ CreateCompatibleBitmap,'CreateCompatibleBitmap',\ DeleteObject,'DeleteObject',\ SelectObject,'SelectObject',\ BitBlt,'BitBlt' import gdiplus,\ GdipCreateBitmapFromHBITMAP,'GdipCreateBitmapFromHBITMAP',\ GdipDisposeImage,'GdipDisposeImage',\ GdiplusStartup,'GdiplusStartup',\ GdiplusShutdown,'GdiplusShutdown',\ GdipSaveImageToFile,'GdipSaveImageToFile' end data align 4 DesktopDC dd ? hDeskBMP dd ? dcDeskBMP dd ? hPrevObject dd ? tSI GdiplusStartupInput <> tGDIP dd ? bytesWritten dd ? frDesktopBitmap dd ?
l_inc Да спасибо - с правильным GUID и у меня заработало, только почему-то в инклюдах из SDK Win Server 2003 этого гуида не оказалось, потому и задействавал то что в них нашлось (а перечислялку слепить поленился Что GDI+ весчь замечательная и очень удобная это я не спорю Но есть в ней коварные ньюансы из-за которых имхо начинать осваивать её на асме стоит после того как ТС будет более менее уверенно ориентироваться в обычных api и англоязычных доках Кстати связка GdipCreateBitmapFromHBITMAP + GdipSaveImageToFile по умолчанию сохраняет bitmap не в формате исходного изображения, а в 32 битном виде без палитры, даже если исходная картинка двухцветная так что для красивого решения задачи придётся всё таки определить параметры bitmapa и соответсвующим образом настроить кодек (кстати я так и не понял как это делается даже применительно к "простейшему случаю" - в msdn/psdk пример только для качества jpg, да и то какой-то мутный - на досуге помедитирую
Y_Mur Я так думаю, что и не должно было. С чего бы рекомендовать его искать перечислением и при этом объявлять в хэдерах? Видимо, я в своё время тоже из сети брал. Хотя и перечисление тоже не более десяти строк, а то и меньше: Код (Text): format PE GUI 4.0 include 'win32a.inc' struct GdiplusStartupInput GdiplusVersion dd ? DebugEventCallback dd ? SuppressBackgroundThread dd ? SuppressExternalCodecs dd ? ends struct ImageCodecInfo Clsid dd 4 dup ? FormatID dd 4 dup ? CodecName dd ? DllName dd ? FormatDescription dd ? FilenameExtension dd ? MimeType dd ? Flags dd ? Version dd ? SigCount dd ? SigSize dd ? SigPattern dd ? SigMask dd ? ends struct EncoderParameter GUID dd 4 dup ? NumberOfValues dd ? Type dd ? Value dd ? ends struct EncoderParameters Count dd ? Parameter EncoderParameter <> ends main: invoke GetWindowDC,0 mov dword[DesktopDC],eax invoke GetSystemMetrics,SM_CXSCREEN mov esi,eax ;esi - screen width invoke GetSystemMetrics,SM_CYSCREEN mov edi,eax ;edi - screen height invoke CreateCompatibleBitmap,[DesktopDC],esi,edi mov dword[hDeskBMP],eax invoke CreateCompatibleDC,[DesktopDC] mov dword[dcDeskBMP],eax invoke SelectObject,[dcDeskBMP],[hDeskBMP] invoke BitBlt,[dcDeskBMP],0,0,esi,edi,[DesktopDC],0,0,SRCCOPY mov dword[tSI.GdiplusVersion],1 invoke GdiplusStartup,tGDIP,tSI invoke GdipCreateBitmapFromHBITMAP,[hDeskBMP],0,frDesktopBitmap invoke GdipGetImageEncodersSize,encNum,encSize invoke VirtualAlloc,0,[encSize],MEM_COMMIT,PAGE_READWRITE mov ebx,eax ;ebx - pointer to encoders info memory invoke GdipGetImageEncoders,[encNum],[encSize],eax lea ebp,[ebx-sizeof.ImageCodecInfo] ;ebp - current encoder being enumerated @@: add ebp,sizeof.ImageCodecInfo invoke lstrcmpW,[ebp+ImageCodecInfo.MimeType],encoderMIME test eax,eax jnz @B invoke GdipSaveImageToFile,[frDesktopBitmap],fPath,ebp,NULL invoke VirtualFree,ebx,0,MEM_RELEASE invoke GdipDisposeImage,[frDesktopBitmap] invoke GdiplusShutdown,[tGDIP] invoke DeleteDC,[dcDeskBMP] invoke DeleteObject,[hDeskBMP] invoke ReleaseDC,0,[DesktopDC] invoke ExitProcess,0 fPath du 'C:\Bitmap.bmp',0 encoderMIME du 'image/bmp',0 data import library kernel32,'kernel32.dll',\ user32,'user32.dll',\ gdi32,'gdi32.dll',\ gdiplus,'gdiplus.dll' import kernel32,\ VirtualAlloc,'VirtualAlloc',\ VirtualFree,'VirtualFree',\ ExitProcess,'ExitProcess',\ lstrcmpW,'lstrcmpW' import user32,\ GetWindowDC,'GetWindowDC',\ ReleaseDC,'ReleaseDC',\ GetSystemMetrics,'GetSystemMetrics' import gdi32,\ CreateCompatibleDC,'CreateCompatibleDC',\ DeleteDC,'DeleteDC',\ CreateCompatibleBitmap,'CreateCompatibleBitmap',\ DeleteObject,'DeleteObject',\ SelectObject,'SelectObject',\ BitBlt,'BitBlt' import gdiplus,\ GdipCreateBitmapFromHBITMAP,'GdipCreateBitmapFromHBITMAP',\ GdipDisposeImage,'GdipDisposeImage',\ GdiplusStartup,'GdiplusStartup',\ GdiplusShutdown,'GdiplusShutdown',\ GdipSaveImageToFile,'GdipSaveImageToFile',\ GdipGetImageEncodersSize,'GdipGetImageEncodersSize',\ GdipGetImageEncoders,'GdipGetImageEncoders' end data align 4 DesktopDC dd ? hDeskBMP dd ? dcDeskBMP dd ? encNum dd ? encSize dd ? tSI GdiplusStartupInput <> tGDIP dd ? bytesWritten dd ? frDesktopBitmap dd ?
Y_Mur Насчет настройки параметров энкодера... там тоже проблем особых нету. В выложенных мной примерах я, кстати, оставил описания необходимых структур хотя и не использовал их. Нужен просто массив структур EncoderParameter в рамках структуры EncoderParameters. Для каждого параметра энкодера есть описаный в хэдерах GUID. Собственно достаточно подробно можно найти по той ссылке, которую я давал в 31-м посте. P.S. Имелось в виду "простейший" для реализации с ручным формированием содержимого конечного файла. Для реализации через GDI+ все случаи равны.
hakeem Дык в #41, #43 он и проводит код без использования ClipBorda Пора тебе всё таки засесть за доки и почитать что делают api из того кода