Bonjour,
J'utilise visual studio 2013 sous windows 7 x64:
Mon application qui est écrit en Win32 api pure charge un fichier, certaine lignes contiennent des bannieres et des emoticones, le fichier peut faire plus de 20 000 lignes,
je defile soit par page ou par ligne la fenêtre windows de l'application.
Les images peuvent être des gif, png, bmp, jpg ...
Lorsque je défile par page je voit l'écran qui se redessinne les images, notamment les bannières, je suppose que cela viens de la fonction que j'utilise pour l'affichage des images
à partir d'un stream.
La méthode d'affichage:
(sur le principe cette méthode fonctionne très bien concernant la récupération d'une images à partir d'un stream)
elle est utilisé de la facon suivante:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 HBITMAP ImagesConvert::LoadStreamImageWithGdiPlus(const char * stream, size_t len) { // Initialize GDI+. GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); HGLOBAL hG; HBITMAP hbm = NULL; if ((hG = GlobalAlloc(GPTR, (len) * sizeof(char))) != 0) { char * ptr = NULL; if ((ptr = (char *)GlobalLock(hG)) != 0) { CopyMemory(ptr, stream, len); IStream * s = NULL; if (::CreateStreamOnHGlobal(hG, FALSE, &s) == S_OK) { Gdiplus::Image *imageStream = NULL; // = new Gdiplus::Image(s); imageStream = Gdiplus::Image::FromStream(s); s->Release(); int width = imageStream->GetWidth(); int height = imageStream->GetHeight(); BITMAPINFO bmi; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biClrImportant = 0; bmi.bmiHeader.biClrUsed = 0; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biHeight = height; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biSize = sizeof (bmi.bmiHeader); bmi.bmiHeader.biSizeImage = 0; //calc later bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biXPelsPerMeter = 0; bmi.bmiHeader.biYPelsPerMeter = 0; BYTE* pBmp = NULL; hbm = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void**)&pBmp, NULL, 0); HDC hdcMem = CreateCompatibleDC(NULL); HGDIOBJ hobj = SelectObject(hdcMem, hbm); Graphics graphics(hdcMem); graphics.DrawImage(imageStream, 0, 0); SelectObject(hdcMem, hobj); DeleteDC(hdcMem); if (imageStream) delete imageStream; } ::GlobalUnlock(hG); } GlobalFree(hG); hG = NULL; } Gdiplus::GdiplusShutdown(gdiplusToken); return hbm; }
La méthode CreateImgFromMemory est la suivante:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 //Load image from stream HBITMAP hbm; hbm = ImagesConvert::LoadStreamImageWithGdiPlus(imgBuffer, imgSize);//LoadAnImageFromStream(imgBuffer, imgSize); LONG imgWidth = 0; LONG imgHeight = 0; ViewLog::GetBitmapSize(hbm, imgWidth, imgHeight); const int bitmapWidht = imgWidth; //int yoff = NeatTextOffset(font); PaintRect(hdc, xpos, ypos, bitmapWidht, m_nLineHeight, attr->bg); LONG bmpWidth; if ((bmpWidth = ViewLog::CreateImgFromMemory(GetModuleHandle(NULL), hdc, NULL, xpos, ypos, imgWidth, imgHeight, hbm)) != -1) += bmpWidth; else { xpos += bitmapWidht; }
Après plusieurs recherche sur le net je me suis aperçu qu'il n'existait aucune fonction pour afficher a partir d'un stream des images de plusieurs format différents
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 //Create banniere LONG ViewLog::CreateImgFromMemory(HANDLE hWnd, HDC hdc, const char * imgFile, int x, int y, int imgWidth, int imgHeight, HBITMAP hbm) { LONG bmpWidth; if(hbm == NULL) { DeleteObject(hbm); return -1; } HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hbmOld = (HBITMAP) SelectObject(hdcMem, hbm); //GetBitmapSize(hbm, imgWidth, imgHeight); bmpWidth = imgWidth; BitBlt(hdc, x, y, imgWidth, imgHeight, hdcMem, 0, 0, SRCCOPY); DeleteObject(hbm); SelectObject(hdcMem, hbmOld); DeleteDC(hdcMem); DeleteObject(hbm); return bmpWidth; }
(bmp,gif,jpg,png ..), c'est pour cela que j'ai du utiliser le GDI qui lui le permet.
Pour éviter la lenteur je voulais savoir si il y avait un paramètre au niveau du compilateur ou au niveau du code à positionner, par exemple une instruction de buffering par exemple.
à moins qu'il existe une autre méthode pour afficher une image à partir d'un stream qui prend en compte tout les formats d'images, je pense que ca n'existe pas ou bien peut être une optimisation
de la fonction d'affichage au niveau du BitBlt.
Merci de votre aide.
Partager