Comment reduire la taille d'un BMP ?

cs_Mamelook Messages postés 48 Date d'inscription jeudi 10 juillet 2003 Statut Membre Dernière intervention 27 juillet 2008 - 7 juil. 2007 à 17:23
cs_Mamelook Messages postés 48 Date d'inscription jeudi 10 juillet 2003 Statut Membre Dernière intervention 27 juillet 2008 - 8 juil. 2007 à 02:40
Comment peut t-on reduire la taille d'une image BMP (HBITMAP) ? J'ai entendu parler de la fonction StretchBlt() de l'api windows, mais je voit pas comment on peut faire sa, pouvez vous m'aider ?

7 réponses

SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
7 juil. 2007 à 17:29
0
cs_Mamelook Messages postés 48 Date d'inscription jeudi 10 juillet 2003 Statut Membre Dernière intervention 27 juillet 2008
7 juil. 2007 à 19:10
Dsl mais ji arrive vraiment pas, se que je voudrai faire c'est que cette fonction (que j'ai prit sur une source de ce site [je sai plus laquel]) puissent retourner une image redimentionner :

BITMAPFILEHEADER m_BitmapFileHeader; // Données de la structure BITMAPFILEHEADER du Bitmap
PBITMAPINFOHEADER m_pBitmapInfoHeader; // Pointeur sur la structure BITMAPINFOHEADER du Bitmap
PBITMAPINFO m_pBitmapInfo; // Pointeur sur la structure BITMAPINFO du Bitmap
LPBYTE m_pBitmapData; // Pointeur sur les Data du Bitmap

HDC m_hDcBitmap; // Handle sur le hDc du Bitmap en memoire
HBITMAP m_hBitmap; // Handle sur le Bitmap


bool TakeDesktopSnapshot(void)
{
// Récupération du HWND et du HDC du bureau
HWND hWndWindow = GetDesktopWindow();
HDC hDcWindow = GetWindowDC(hWndWindow);

// On récupére les dimensions du bureau
int ScreenX = GetDeviceCaps(hDcWindow, HORZRES);
int ScreenY = GetDeviceCaps(hDcWindow, VERTRES);

// Création d'un contexte mémoire
m_hDcBitmap = CreateCompatibleDC(hDcWindow);
if(!m_hDcBitmap) return 0;

// On crée un bitmap en mémoire ayant les dimensions du bureau
HBITMAP hBitmap = CreateCompatibleBitmap(hDcWindow, ScreenX, ScreenY);
if(!hBitmap) return 0;

// On sélectionne ce bitmap dans le contexte mémoire
if(!SelectObject(m_hDcBitmap, hBitmap)) return 0;

// On effectue une copie du contexte écran vers le contexte mémoire
if(!BitBlt(m_hDcBitmap, 0, 0, ScreenX, ScreenY, hDcWindow, 0, 0, SRCCOPY)) return 0;

// Maintenant on crée la structure BITMAPINFO
BITMAP Bitmap;
WORD Couleur;

// Récupération de la structure BITMAP
if (!GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap)) return 0;

// Convertie le format de couleur
Couleur = (WORD)(Bitmap.bmPlanes * Bitmap.bmBitsPixel);
if (Couleur 1) Couleur 1;
else if (Couleur <4) Couleur 4;
else if (Couleur <8) Couleur 8;
else if (Couleur <16) Couleur 16;
else if (Couleur <24) Couleur 24;
else Couleur = 32;

// Alloue de la memoire pour la structure BITMAPINFO (Cette structure
// contient une structure BITMAPINFOHEADER et un tableau de RGBQUAD
if (Couleur != 24)
m_pBitmapInfo = (PBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1<< Couleur)];

// Il n'y a pas de tableau de RGBQUAD pour le format 24 bit

else
m_pBitmapInfo = (PBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];

if(!m_pBitmapInfo) return 0;

// Initialise la structure BITMAPINFO

m_pBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_pBitmapInfo->bmiHeader.biWidth = Bitmap.bmWidth;
m_pBitmapInfo->bmiHeader.biHeight = Bitmap.bmHeight;
m_pBitmapInfo->bmiHeader.biPlanes = Bitmap.bmPlanes;
m_pBitmapInfo->bmiHeader.biBitCount = Bitmap.bmBitsPixel;
if (Couleur < 24)
m_pBitmapInfo->bmiHeader.biClrUsed = (1<<Couleur);

// If the bitmap is not compressed, set the BI_RGB flag.
m_pBitmapInfo->bmiHeader.biCompression = BI_RGB;
m_pBitmapInfo->bmiHeader.biSizeImage = ((m_pBitmapInfo->bmiHeader.biWidth * Couleur +31) & ~31) /8 * m_pBitmapInfo->bmiHeader.biHeight;

// Set biClrImportant to 0, indicating that all of the
// device colors are important.
m_pBitmapInfo->bmiHeader.biClrImportant = 0;

//initialise le reste des structures...

m_pBitmapInfoHeader = (PBITMAPINFOHEADER) m_pBitmapInfo;

m_pBitmapData = new BYTE[m_pBitmapInfoHeader->biSizeImage];
if (!m_pBitmapData) return 0;

// Retrieve the color table (RGBQUAD array) and the bits
// (array of palette indices) from the DIB.
if (!GetDIBits(m_hDcBitmap, hBitmap, 0, (WORD) m_pBitmapInfoHeader->biHeight, m_pBitmapData, m_pBitmapInfo, DIB_RGB_COLORS)) return 0;

m_BitmapFileHeader.bfType 0x4d42; // 0x42 "B" 0x4d = "M"

// Compute the size of the entire file.
m_BitmapFileHeader.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + m_pBitmapInfoHeader->biSize + m_pBitmapInfoHeader->biClrUsed * sizeof(RGBQUAD) + m_pBitmapInfoHeader->biSizeImage);
m_BitmapFileHeader.bfReserved1 = 0;
m_BitmapFileHeader.bfReserved2 = 0;

// Compute the offset to the array of color indices.
m_BitmapFileHeader.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + m_pBitmapInfoHeader->biSize + m_pBitmapInfoHeader->biClrUsed * sizeof (RGBQUAD);

return 1;
}

Comment faire ?
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
7 juil. 2007 à 20:47
Pk tu tiens absolument à bouffer du bmp ? Ya plein de petites librairies (ou grosse) pour lire un bmp. Tu en obtiens alors facilement le buffer de données. Tu le redimensionnes et tu utilises de nouveau la librairie pour sauvegarder le nouveau bmp.
0
cs_Mamelook Messages postés 48 Date d'inscription jeudi 10 juillet 2003 Statut Membre Dernière intervention 27 juillet 2008
7 juil. 2007 à 21:12
Et bien, les librairy que j'ai vue sont bien trop lourde (plus de 100ko), j'ai un cahier des charges a respecter, donc pour l'instan c'est a bannir ...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
7 juil. 2007 à 22:07
LoadImage
SelectObject du HBITMAP retourné sur un DC mémoire créé avec CreateCompatibleDC
StretchBlt sur DC principal récupéré avec GetDC et le tour est joué.

Voici un exemple complet. L'image IMAGE_NAME est redimensionné selon les dimensions de la fenêtre:

#include <windows.h>


#define IMAGE_NAME "sak.bmp"


HBITMAP hBmp;

BITMAP bmp;

HDC hDC, hMemDC;
int w = 0, h = 0;


LRESULT __stdcall WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

  switch(message) {

    case WM_CREATE: {

      hDC = GetDC(hwnd);

      hMemDC = CreateCompatibleDC(hDC);

      hBmp = LoadImage(0, IMAGE_NAME, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

      SelectObject(hMemDC, hBmp);

      GetObject(hBmp, sizeof(bmp), &bmp);

    } break;


    case WM_SIZE:

      w = LOWORD(lParam);

      h = HIWORD(lParam);

      StretchBlt(hDC, 0, 0, w, h, hMemDC, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);

      break;


    case WM_PAINT: {

      PAINTSTRUCT ps;

      HDC hdc = BeginPaint(hwnd, &ps);

      StretchBlt(hdc, 0, 0, w, h, hMemDC, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);

      EndPaint(hwnd, &ps);

    } break;


    case WM_DESTROY:

      ReleaseDC(hwnd, hDC);

      DeleteDC(hMemDC);

      PostQuitMessage(0);

      break;


    default: return DefWindowProc(hwnd, message, wParam, lParam);

  }


  return 0;

}

int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmd, int scmd)

{

  HWND hwnd;

  WNDCLASSEX wcex;


  wcex.cbSize = sizeof(WNDCLASSEX); 

  wcex.style = 0;

  wcex.lpfnWndProc = WndProc;

  wcex.cbClsExtra = 0; wcex.cbWndExtra = 0;

  wcex.hInstance = hInstance;

  wcex.hIcon = 0; wcex.hIconSm = 0;

  wcex.hCursor = LoadCursor(0, IDC_ARROW);

  wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW);

  wcex.lpszMenuName = 0;

  wcex.lpszClassName = "RedimBmp";


  if(RegisterClassEx(&wcex)) {

    if(hwnd = CreateWindow("RedimBmp", "RedimBmp", WS_OVERLAPPEDWINDOW, 

      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInstance, 0)) {

      MSG msg;


      ShowWindow(hwnd, SW_NORMAL);


      while(GetMessage(&msg, 0, 0, 0)) {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

      }

    }

  }


  return 0;

}

Coloration réalisé avec CodeFormatter

C++ (@++)<!--
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
7 juil. 2007 à 22:08
Oue peut etre, mais une source comme celle-ci pèse pas 100ko et peut simplifier la vie.
http://www.cppfrance.com/codes/LOADER-BMP-TRAITEMENT_33150.aspx

Apres, c'est toi qui vois :)
0
cs_Mamelook Messages postés 48 Date d'inscription jeudi 10 juillet 2003 Statut Membre Dernière intervention 27 juillet 2008
8 juil. 2007 à 02:40
Merci pour vos réponse, je vien de trouver la source qui me fallai !
http://www.cppfrance.com/codes_image/normal/20758.aspx

La taille de l'image generer est tres faible, mais c'est la qualiter qui me gene, quelqu'un serait comment faire pour augmenter la qualiter ?
0
Rejoignez-nous