Pas de dépendances
#include <windows.h> #include <stdio.h> void Dessiner(int width,int height,const char* flux) { int i,j,curs; HWND Hcon = GetConsoleWindow(); HDC Hdc = GetDC(Hcon); for(curs=0,j=height-1;j>=0;j--) { for(i=0;i<width;i++,curs+=4) { COLORREF COLOR = RGB(flux[curs+2],flux[curs+1],flux[curs]); SetPixel(Hdc,i,j,COLOR); } } ReleaseDC(Hcon, Hdc); } int main(void) { if(OpenClipboard(NULL)) { HANDLE h; h = GetClipboardData(CF_DIBV5); if(h) { BITMAPV5HEADER head; char *brut = (char *)GlobalLock(h); head = *((BITMAPV5HEADER*)brut); Dessiner(head.bV5Width,head.bV5Height,brut+head.bV5Size); GlobalUnlock(h); CloseClipboard(); } else printf("Pas d'image dans le presse papier\n"); CloseClipboard(); } return 0; }
Pour tester ce code, ouvrez l'outile de capture, ou bien paint, ou bien la touche du clavier "impr ecran" ou bien n'importe quel logiciel qui vous permette de copier une image ou un bout d'image. Bref, mettez une image dans le presse papier Windows. Lancez le programme, il va vous afficher l'image dans la console. (c'est un peu lent, donc si vous avez une très grande image, patientez quelques secondes). Le programme ouvre le presse papier, regarde si il y a des informations de type image, et l'affiche. Si on regarde le main : J'ouvre le ClipBoard (presse papier). Ensuite, je regade s'il y a une image dedans. le format usuel s'appelle CF_DIBV5. Si ce n'est pas le cas on quitte. Les données récupérées dans le char* brut ressemble au format BMP, c'est à dire un header, puis les pixels. La structure BITMAPV5HEADER épouse les premiers octets du flux. En castant le char* dessus, on a toutes les données bien rangées. Voici ces données : typedef struct { DWORD bV5Size; LONG bV5Width; LONG bV5Height; WORD bV5Planes; WORD bV5BitCount; DWORD bV5Compression; DWORD bV5SizeImage; LONG bV5XPelsPerMeter; LONG bV5YPelsPerMeter; DWORD bV5ClrUsed; DWORD bV5ClrImportant; DWORD bV5RedMask; DWORD bV5GreenMask; DWORD bV5BlueMask; DWORD bV5AlphaMask; DWORD bV5CSType; CIEXYZTRIPLE bV5Endpoints; DWORD bV5GammaRed; DWORD bV5GammaGreen; DWORD bV5GammaBlue; DWORD bV5Intent; DWORD bV5ProfileData; DWORD bV5ProfileSize; DWORD bV5Reserved; } BITMAPV5HEADER, FAR *LPBITMAPV5HEADER, *PBITMAPV5HEADER; Si vous posez un breakpoint dessus, vous pouvez voir (entre autres) : - bV5Size : la taille de ce header : ainsi, un décalage de bV5Size ira sur les données pixel - bV5Width : le nombre de pixels en X - bV5Height : le nombre de pixels en Y Pour voir les autres champs : http://msdn.microsoft.com/en-us/library/windows/desktop/dd183381%28v=vs.85%29.aspx Ma fonction Dessiner part du principe que le format me convient, je ne teste pas les différents cas. Si ça foire chez vous (vous avez un affichage moche, un plantage, envoyez moi un mail pour me dire de quelle façon vous avez fait votre screenshot, je suis curieux de savoir dans quel cas les screenshots établissent un autre format :) ) Ce que je passe à ma fonction Dessiner, c'est donc le width, le height, ainsi que le pointeur au début du bloc de pixels. La fonction Dessiner dessine les pixels de gauche à droite, et de bas à en haut, ainsi le veut la norme bitmap. Voila pourquoi le for du j décrémente. Chaque pixel est codé sur 4 octets (voila pourquoi je fais curs+=4) Chaque pixel est de la forme BGRA : bleu, vert, rouge, alpha J'ignore l'alpha, je ne me sers que du bleu, vert, rouge. Comme la fonction RGB prend rouge, vert, bleu, je passe d'abord l'octet curs+2, puis curs+1, puis curs (+0)