[Delphi] вопрос по BitBlt

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Lotrein, 4 Mar 2012.

  1. Lotrein

    Lotrein New Member

    Joined:
    13 Dec 2011
    Messages:
    13
    Likes Received:
    0
    Reputations:
    0
    с помощью BitBlt сохранял скрин своего экрана 1920х1080, изображение набирает 7,91 мб веса. Как уменьшить вес изображения??
     
  2. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Перекодировать его перед сохранением в формат, использующий сжатие (JPEG, PNG, GIF и т.п.). По дельфовому API не могу подсказать, но наверняка есть какие-то библиотеки для этого.
     
  3. enigma

    enigma Member

    Joined:
    10 Jul 2011
    Messages:
    80
    Likes Received:
    15
    Reputations:
    7
    Вроде у класса Bitmap есть метод GetThumbnailImage, и там можно задавать параметры, ширину и высоту картинки.

    С помощью GDI+ снять скриншот, и сохранить в jpg, переделай на delphi
    Code:
    #include <Windows.h>
    #include <GdiPlus.h>
    using namespace Gdiplus; 
    #pragma comment(lib, "GdiPlus.lib") 
    
    int EncodeClsid(WCHAR *format, CLSID *pClsid)
    {
    	unsigned int n = 0,  size = 0;
    	GetImageEncodersSize(&n, &size);
    	if(size == 0) return -1;
    	ImageCodecInfo *pImageCodecInfo = (ImageCodecInfo *)(malloc(size));
    	if(pImageCodecInfo == NULL) return -1;
    	GetImageEncoders(n, size, pImageCodecInfo);
    	for(unsigned int j = 0; j < n; ++j){
    		if(wcscmp(pImageCodecInfo[j].MimeType, format) == 0){
    			*pClsid = pImageCodecInfo[j].Clsid;
    			free(pImageCodecInfo);
    			return j;
    		}    
    	}
    	free(pImageCodecInfo);
    	return -1;
    }
    
    int GetScr(LPWSTR lpszFilename, ULONG uQuality) 
    {
        ULONG_PTR gdiplusToken;
    	GdiplusStartupInput gdiplusStartupInput;
    	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    	
    	HDC hdcScr  = CreateDC("DISPLAY", NULL, NULL, NULL);
    	HDC hdcCapture = CreateCompatibleDC(hdcScr);
    	int nWidth     = GetDeviceCaps(hdcScr, HORZRES),
    	    nHeight    = GetDeviceCaps(hdcScr, VERTRES),
    	    nBPP       = GetDeviceCaps(hdcScr, BITSPIXEL);
    	
    	LPBYTE lpCapture;
    	BITMAPINFO bmiCapture = { {
    		sizeof(BITMAPINFOHEADER), nWidth, -nHeight, 1, nBPP, BI_RGB, 0, 0, 0, 0, 0,
    	} };
    	HBITMAP hbmCapture = CreateDIBSection(hdcScr, &bmiCapture,
    		DIB_PAL_COLORS, (LPVOID *)&lpCapture, NULL, 0);
    	if(!hbmCapture){
    		DeleteDC(hdcCapture);
    		DeleteDC(hdcScr);
    		GdiplusShutdown(gdiplusToken);
    		return 1;
    	}
    	
    	int nCapture = SaveDC(hdcCapture);
    	SelectObject(hdcCapture, hbmCapture);
    	BitBlt(hdcCapture, 0, 0, nWidth, nHeight, hdcScr, 0, 0, SRCCOPY);
    	RestoreDC(hdcCapture, nCapture);
    	DeleteDC(hdcCapture);
    	DeleteDC(hdcScr);
    	
    	CLSID imgCLSID;
    	Bitmap *pScreenShot = new Bitmap(hbmCapture, (HPALETTE)NULL);
    	EncoderParameters encodeParam;
    	encodeParam.Count = 1;
    	encodeParam.Parameter[0].NumberOfValues = 1;
    	encodeParam.Parameter[0].Guid  = EncoderQuality;
    	encodeParam.Parameter[0].Type  = EncoderParameterValueTypeLong;
    	encodeParam.Parameter[0].Value = &uQuality;
    	EncodeClsid(L"image/jpeg", &imgCLSID);
    	int res = (pScreenShot->Save(lpszFilename, &imgCLSID, &encodeParam) == Ok);
    	delete pScreenShot;
    	DeleteObject(hbmCapture);
    	GdiplusShutdown(gdiplusToken);
    	return res;
    }
    
     int WINAPI WinMain(HINSTANCE hI,  HINSTANCE hPInst, PSTR szCmdLine,  int iCmdShow)   
    
    {
    
    GetScr(L"scr.jpg", 10); //второй параметр зададим степень сжатия картинки
    return 0;
    }