Accueil > > > ETIRER/RÉTRÉCIR UNE IMAGE BMP SANS STRETCHBLT
ETIRER/RÉTRÉCIR UNE IMAGE BMP SANS STRETCHBLT
Information sur la source
Description
C'est un code qui permet de changer la résolution d'une image avec deux méthodes pour l'agrandissement (avec ou sans moyenne) Le principe est expliqué dans un fichier txt joint dans le zip 3 fonctions : lire un bmp24 bits, le scaler, et l'enregistrer Lancez le prog, il ouvrira image.bmp et créera une image de double taille avec ou sans la moyenne et une image de taille la moitié. On peut aussi stretcher l'image comme l'on veut : agrandir un coté et rétrecir l'autre, ou toute autre configuration
Source
- /*-----------------------------------------------------------------------------------------------*
- //
- // ScaleImage
- //
- //Fait par : MaegisInstinct (maegisinstinct@free.fr)
- //
- //le : 29/07/2004 à 20:27:37
- //
- //Description : Permet d'etirer/étrecir une image
- Lire le .txt pour avoir des explications sur la méthode de Scale
- //
- /*----------------------------------------------------------------------------------------------*/
-
- #include <windows.h>
-
- #define PARTDEC(a) (a-(double)(int)a) //retourne la partie décimale d'un double
-
- struct PIXEL
- {
- BYTE b;
- BYTE g;
- BYTE r;
- };
-
-
- /*--------------------------------*/
- //Change la resolution d'une image
- /*--------------------------------*/
- void Scale(const PIXEL* src,DWORD srcwidth,DWORD srcheight,PIXEL* data,DWORD datawidth,DWORD dataheight,BOOL moyenne_etirement)
- {
- DWORD i,j,k,l;
- PIXEL* save_data;
- double xratio,yratio;
- double precx = 0.0,precy = 0.0;
- double currentx,currenty;
- double coeff; //somme des coeffs pour la moyenne
- double temp;
- double somme_r,somme_g,somme_b;
-
- xratio = (double)srcwidth/(double)datawidth;
- yratio = (double)srcheight/(double)dataheight;
- save_data = data;
- currenty = 0.0;
-
- for(j=0;j<dataheight;j++) //Pour chaque pixel du but
- {
- currentx = 0.0;
- currenty += yratio;
- for(i=0;i<datawidth;i++)
- {
- currentx += xratio;
- coeff = 0.0;
- somme_r = 0.0;
- somme_g = 0.0;
- somme_b = 0.0;
-
- //Calcul de la moyenne
- for(l=0;l<(unsigned int)yratio+1;l++) //Pour chaque pixel de la source contenu dans le pixel du but
- {
- for(k=0;k<(unsigned int)xratio+1;k++)
- {
- //Coeff en x
- if (k==0)
- temp = 1.0-PARTDEC(precx);
- else if (k==(unsigned int)xratio)
- temp = xratio-(double)((int)xratio-1)-(1.0-PARTDEC(precx));
- else
- temp = 1;
- //Coeff en y
- if (l==0)
- temp = temp*(1.0-PARTDEC(precy));
- else if (l==(unsigned int)yratio)
- temp = temp*(yratio-(double)((int)yratio-1)-(1.0-PARTDEC(precy)));
-
- if ((int)precx+k<srcwidth && (int)precy+l<srcheight) //si on est dans les limites
- {
- somme_r += src[(int)precx+k+((int)precy+l)*srcwidth].r*temp;
- somme_g += src[(int)precx+k+((int)precy+l)*srcwidth].g*temp;
- somme_b += src[(int)precx+k+((int)precy+l)*srcwidth].b*temp;
- coeff += temp;
- }
-
- if (moyenne_etirement) //Moyenne lors de l'etirement si souhaité
- {
- if (xratio<1. && (int)currentx-(int)precx==1 && PARTDEC(currentx) != 0.)
- {
- temp = PARTDEC(currentx);
- somme_r += src[(int)precx+1 + (int)precy*srcwidth].r*temp;
- somme_g += src[(int)precx+1 + (int)precy*srcwidth].g*temp;
- somme_b += src[(int)precx+1 + (int)precy*srcwidth].b*temp;
- coeff += temp;
- temp = -1.0;
- }
- if (yratio<1. && (int)currenty-(int)precy==1 && PARTDEC(currenty) != 0.)
- {
- if (temp == -1.0) //on compte le quatrieme carré
- {
- temp = PARTDEC(currenty)*PARTDEC(currentx);
- somme_r += src[(int)precx+1 + ((int)(precy)+1)*srcwidth].r*temp;
- somme_g += src[(int)precx+1 + ((int)(precy)+1)*srcwidth].g*temp;
- somme_b += src[(int)precx+1 + ((int)(precy)+1)*srcwidth].b*temp;
- coeff += temp;
- }
- temp = PARTDEC(currenty);
- somme_r += src[(int)precx + ((int)(precy)+1)*srcwidth].r*temp;
- somme_g += src[(int)precx + ((int)(precy)+1)*srcwidth].g*temp;
- somme_b += src[(int)precx + ((int)(precy)+1)*srcwidth].b*temp;
- coeff += temp;
- }
- }
- }
- }
- data->r = (BYTE)(somme_r/coeff);
- data->g = (BYTE)(somme_g/coeff);
- data->b = (BYTE)(somme_b/coeff);
- data++;
- precx = currentx;
- }
- precy = currenty;
- precx = 0.0;
- }
- data = save_data;
- }
-
- /*---------------------------------*/
- //Enregistre un fichier bmp24 bits
- /*---------------------------------*/
- BOOL SaveBmp24(char *path,PIXEL *data,int width,int height)
- {
- BITMAPFILEHEADER fileheader;
- BITMAPINFOHEADER infoheader;
- HANDLE fichier;
- DWORD dummy;
- int size;
- int bourrage = 0;
- int i,j,k;
- char *image = NULL;
-
- fichier = CreateFile(path,
- GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (fichier == INVALID_HANDLE_VALUE)
- return FALSE;
-
- fileheader.bfType = 0x4D42; //"bm"
- fileheader.bfSize = 54 + width*height*3;
- fileheader.bfReserved2 = 0;
- fileheader.bfReserved1 = 0;
- fileheader.bfOffBits = 54;
-
- infoheader.biSize = sizeof(BITMAPINFOHEADER);
- infoheader.biWidth = width;
- infoheader.biHeight = height;
- infoheader.biPlanes = 1;
- infoheader.biBitCount = 24;
- infoheader.biCompression = 0;
- infoheader.biSizeImage = width*height;
- infoheader.biXPelsPerMeter = 0;
- infoheader.biYPelsPerMeter = 0;
- infoheader.biClrImportant = 0;
- infoheader.biClrUsed = 0;
-
- while ((3*width+bourrage) % 4 != 0) //calcul du nb de bits de bourrage (3 car 24bits = 3octs)
- bourrage++;
-
- size = width*height;
-
- image = new char[size*3+bourrage*height];
- if (image == NULL)
- {
- CloseHandle(fichier);
- return FALSE;
- }
-
- for(i=0;i<height;i++)
- {
- for(j=0;j<width;j++)
- {
- image[i*(3*width+bourrage)+3*j] = data[(height-i-1)*width+j].b;
- image[i*(3*width+bourrage)+3*j+1] = data[(height-i-1)*width+j].g;
- image[i*(3*width+bourrage)+3*j+2] = data[(height-i-1)*width+j].r;
- }
- for(k=1;k<bourrage;k++)
- image[i*(3*width+bourrage)+3*j+k] = 0;
- }
-
- WriteFile(fichier,&fileheader,14,&dummy,NULL);
- WriteFile(fichier,&infoheader,40,&dummy,NULL);
- WriteFile(fichier,image,size*3+bourrage*height,&dummy,NULL);
-
- CloseHandle(fichier);
- return TRUE;
- }
-
- /*---------------------*/
- //Ouvre un bmp 24 bits
- /*---------------------*/
- BOOL GetBmp24(char* chemin,PIXEL **data,DWORD& width,DWORD& height)
- {
- BITMAPFILEHEADER fileheader;
- BITMAPINFOHEADER infoheader;
- HANDLE fichier;
- DWORD dummy,i,j;
- DWORD size;
- DWORD bourrage = 0;
- PIXEL temp;
- BYTE *buffer = NULL;
-
- fichier = CreateFile(chemin,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (fichier == INVALID_HANDLE_VALUE)
- return FALSE;
-
- ReadFile(fichier,&fileheader,14,&dummy,NULL);
- ReadFile(fichier,&infoheader,40,&dummy,NULL);
- width = infoheader.biWidth;
- height = infoheader.biHeight;
-
- while ((3*width+bourrage) % 4 != 0) //gestion du bourrage
- bourrage++;
-
- if (fileheader.bfType != 0x4D42 || infoheader.biBitCount != 24
- || infoheader.biCompression != 0)
- {
- CloseHandle(fichier);
- return FALSE;
- }
- size = width*height;
-
- buffer = new BYTE[size*3+bourrage*height];
- if (buffer == NULL)
- return FALSE;
-
- SetFilePointer(fichier,fileheader.bfOffBits,NULL,FILE_BEGIN);
-
- ReadFile(fichier,buffer,size*3+bourrage*height,&dummy,NULL);
-
- (*data) = new PIXEL[size];
- if ((*data) == NULL)
- {
- delete[] buffer;
- return FALSE;
- }
-
- for(i=0;i<height;i++)
- {
- memcpy((*data)+(i*width),buffer+i*(3*width+bourrage),width*3);
- }
-
- //remet dans le bon sens
- for(i=0;i<(height/2);i++)
- {
- for(j=0;j<width;j++)
- {
- temp = (*data)[i*width+j];
- (*data)[i*width+j] = (*data)[(height-1-i)*width+j];
- (*data)[(height-1-i)*width+j] = temp;
- }
- }
-
-
- CloseHandle(fichier);
- delete[] buffer;
- return TRUE;
- }
-
- /*--------------*/
- //Fonction Main
- /*--------------*/
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nShowCmd)
- {
- PIXEL *data,*scaleddata;
- DWORD width,height;
-
- if (GetBmp24("image.bmp",&data,width,height))
- {
- scaleddata = new PIXEL[width*height*4];
- Scale(data,width,height,scaleddata,width/2,height/2,FALSE);
- SaveBmp24("Halfimage.bmp",scaleddata,width/2,height/2);
- Scale(data,width,height,scaleddata,width*2,height*2,FALSE);
- SaveBmp24("Doubleimage.bmp",scaleddata,width*2,height*2);
- Scale(data,width,height,scaleddata,width*2,height*2,TRUE);
- SaveBmp24("Doubleimagemoyenne.bmp",scaleddata,width*2,height*2);
-
- delete[] data;
- delete[] scaleddata;
- return 0;
- }
- return -1;
- }
/*-----------------------------------------------------------------------------------------------*
//
// ScaleImage
//
//Fait par : MaegisInstinct (maegisinstinct@free.fr)
//
//le : 29/07/2004 à 20:27:37
//
//Description : Permet d'etirer/étrecir une image
Lire le .txt pour avoir des explications sur la méthode de Scale
//
/*----------------------------------------------------------------------------------------------*/
#include <windows.h>
#define PARTDEC(a) (a-(double)(int)a) //retourne la partie décimale d'un double
struct PIXEL
{
BYTE b;
BYTE g;
BYTE r;
};
/*--------------------------------*/
//Change la resolution d'une image
/*--------------------------------*/
void Scale(const PIXEL* src,DWORD srcwidth,DWORD srcheight,PIXEL* data,DWORD datawidth,DWORD dataheight,BOOL moyenne_etirement)
{
DWORD i,j,k,l;
PIXEL* save_data;
double xratio,yratio;
double precx = 0.0,precy = 0.0;
double currentx,currenty;
double coeff; //somme des coeffs pour la moyenne
double temp;
double somme_r,somme_g,somme_b;
xratio = (double)srcwidth/(double)datawidth;
yratio = (double)srcheight/(double)dataheight;
save_data = data;
currenty = 0.0;
for(j=0;j<dataheight;j++) //Pour chaque pixel du but
{
currentx = 0.0;
currenty += yratio;
for(i=0;i<datawidth;i++)
{
currentx += xratio;
coeff = 0.0;
somme_r = 0.0;
somme_g = 0.0;
somme_b = 0.0;
//Calcul de la moyenne
for(l=0;l<(unsigned int)yratio+1;l++) //Pour chaque pixel de la source contenu dans le pixel du but
{
for(k=0;k<(unsigned int)xratio+1;k++)
{
//Coeff en x
if (k==0)
temp = 1.0-PARTDEC(precx);
else if (k==(unsigned int)xratio)
temp = xratio-(double)((int)xratio-1)-(1.0-PARTDEC(precx));
else
temp = 1;
//Coeff en y
if (l==0)
temp = temp*(1.0-PARTDEC(precy));
else if (l==(unsigned int)yratio)
temp = temp*(yratio-(double)((int)yratio-1)-(1.0-PARTDEC(precy)));
if ((int)precx+k<srcwidth && (int)precy+l<srcheight) //si on est dans les limites
{
somme_r += src[(int)precx+k+((int)precy+l)*srcwidth].r*temp;
somme_g += src[(int)precx+k+((int)precy+l)*srcwidth].g*temp;
somme_b += src[(int)precx+k+((int)precy+l)*srcwidth].b*temp;
coeff += temp;
}
if (moyenne_etirement) //Moyenne lors de l'etirement si souhaité
{
if (xratio<1. && (int)currentx-(int)precx==1 && PARTDEC(currentx) != 0.)
{
temp = PARTDEC(currentx);
somme_r += src[(int)precx+1 + (int)precy*srcwidth].r*temp;
somme_g += src[(int)precx+1 + (int)precy*srcwidth].g*temp;
somme_b += src[(int)precx+1 + (int)precy*srcwidth].b*temp;
coeff += temp;
temp = -1.0;
}
if (yratio<1. && (int)currenty-(int)precy==1 && PARTDEC(currenty) != 0.)
{
if (temp == -1.0) //on compte le quatrieme carré
{
temp = PARTDEC(currenty)*PARTDEC(currentx);
somme_r += src[(int)precx+1 + ((int)(precy)+1)*srcwidth].r*temp;
somme_g += src[(int)precx+1 + ((int)(precy)+1)*srcwidth].g*temp;
somme_b += src[(int)precx+1 + ((int)(precy)+1)*srcwidth].b*temp;
coeff += temp;
}
temp = PARTDEC(currenty);
somme_r += src[(int)precx + ((int)(precy)+1)*srcwidth].r*temp;
somme_g += src[(int)precx + ((int)(precy)+1)*srcwidth].g*temp;
somme_b += src[(int)precx + ((int)(precy)+1)*srcwidth].b*temp;
coeff += temp;
}
}
}
}
data->r = (BYTE)(somme_r/coeff);
data->g = (BYTE)(somme_g/coeff);
data->b = (BYTE)(somme_b/coeff);
data++;
precx = currentx;
}
precy = currenty;
precx = 0.0;
}
data = save_data;
}
/*---------------------------------*/
//Enregistre un fichier bmp24 bits
/*---------------------------------*/
BOOL SaveBmp24(char *path,PIXEL *data,int width,int height)
{
BITMAPFILEHEADER fileheader;
BITMAPINFOHEADER infoheader;
HANDLE fichier;
DWORD dummy;
int size;
int bourrage = 0;
int i,j,k;
char *image = NULL;
fichier = CreateFile(path,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fichier == INVALID_HANDLE_VALUE)
return FALSE;
fileheader.bfType = 0x4D42; //"bm"
fileheader.bfSize = 54 + width*height*3;
fileheader.bfReserved2 = 0;
fileheader.bfReserved1 = 0;
fileheader.bfOffBits = 54;
infoheader.biSize = sizeof(BITMAPINFOHEADER);
infoheader.biWidth = width;
infoheader.biHeight = height;
infoheader.biPlanes = 1;
infoheader.biBitCount = 24;
infoheader.biCompression = 0;
infoheader.biSizeImage = width*height;
infoheader.biXPelsPerMeter = 0;
infoheader.biYPelsPerMeter = 0;
infoheader.biClrImportant = 0;
infoheader.biClrUsed = 0;
while ((3*width+bourrage) % 4 != 0) //calcul du nb de bits de bourrage (3 car 24bits = 3octs)
bourrage++;
size = width*height;
image = new char[size*3+bourrage*height];
if (image == NULL)
{
CloseHandle(fichier);
return FALSE;
}
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
{
image[i*(3*width+bourrage)+3*j] = data[(height-i-1)*width+j].b;
image[i*(3*width+bourrage)+3*j+1] = data[(height-i-1)*width+j].g;
image[i*(3*width+bourrage)+3*j+2] = data[(height-i-1)*width+j].r;
}
for(k=1;k<bourrage;k++)
image[i*(3*width+bourrage)+3*j+k] = 0;
}
WriteFile(fichier,&fileheader,14,&dummy,NULL);
WriteFile(fichier,&infoheader,40,&dummy,NULL);
WriteFile(fichier,image,size*3+bourrage*height,&dummy,NULL);
CloseHandle(fichier);
return TRUE;
}
/*---------------------*/
//Ouvre un bmp 24 bits
/*---------------------*/
BOOL GetBmp24(char* chemin,PIXEL **data,DWORD& width,DWORD& height)
{
BITMAPFILEHEADER fileheader;
BITMAPINFOHEADER infoheader;
HANDLE fichier;
DWORD dummy,i,j;
DWORD size;
DWORD bourrage = 0;
PIXEL temp;
BYTE *buffer = NULL;
fichier = CreateFile(chemin,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fichier == INVALID_HANDLE_VALUE)
return FALSE;
ReadFile(fichier,&fileheader,14,&dummy,NULL);
ReadFile(fichier,&infoheader,40,&dummy,NULL);
width = infoheader.biWidth;
height = infoheader.biHeight;
while ((3*width+bourrage) % 4 != 0) //gestion du bourrage
bourrage++;
if (fileheader.bfType != 0x4D42 || infoheader.biBitCount != 24
|| infoheader.biCompression != 0)
{
CloseHandle(fichier);
return FALSE;
}
size = width*height;
buffer = new BYTE[size*3+bourrage*height];
if (buffer == NULL)
return FALSE;
SetFilePointer(fichier,fileheader.bfOffBits,NULL,FILE_BEGIN);
ReadFile(fichier,buffer,size*3+bourrage*height,&dummy,NULL);
(*data) = new PIXEL[size];
if ((*data) == NULL)
{
delete[] buffer;
return FALSE;
}
for(i=0;i<height;i++)
{
memcpy((*data)+(i*width),buffer+i*(3*width+bourrage),width*3);
}
//remet dans le bon sens
for(i=0;i<(height/2);i++)
{
for(j=0;j<width;j++)
{
temp = (*data)[i*width+j];
(*data)[i*width+j] = (*data)[(height-1-i)*width+j];
(*data)[(height-1-i)*width+j] = temp;
}
}
CloseHandle(fichier);
delete[] buffer;
return TRUE;
}
/*--------------*/
//Fonction Main
/*--------------*/
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
PIXEL *data,*scaleddata;
DWORD width,height;
if (GetBmp24("image.bmp",&data,width,height))
{
scaleddata = new PIXEL[width*height*4];
Scale(data,width,height,scaleddata,width/2,height/2,FALSE);
SaveBmp24("Halfimage.bmp",scaleddata,width/2,height/2);
Scale(data,width,height,scaleddata,width*2,height*2,FALSE);
SaveBmp24("Doubleimage.bmp",scaleddata,width*2,height*2);
Scale(data,width,height,scaleddata,width*2,height*2,TRUE);
SaveBmp24("Doubleimagemoyenne.bmp",scaleddata,width*2,height*2);
delete[] data;
delete[] scaleddata;
return 0;
}
return -1;
}
Conclusion
La difference en l'agrandissement avec ou sans la moyenne se voit sur des petites images (Essayez sur des 8*8 ou 16*16 ou sur des icones à agrandir fortement)
Sources du même auteur
Sources de la même categorie
Commentaires et avis
|
Derniers Blogs
[TECHDAYS 2010] #04 - WORKSHOP : UPGRADE DE MOSS 2007 VERS SHAREPOINT 2010[TECHDAYS 2010] #04 - WORKSHOP : UPGRADE DE MOSS 2007 VERS SHAREPOINT 2010 par pierre
Alain Bastardie (Consultant SQLi) présente le workshop d'upgrade de MOSS 2007 vers SharePoint 2010. Philisophie de la migration Faire un état des lieux avant de démarrer Utiliser des outils sur MOSS 2007 Résoudre les problèmes potent...
Cliquez pour lire la suite de l'article par pierre TECHDAYS PARIS 2010 : LA GOUVERNANCE DANS SHAREPOINT ONLINETECHDAYS PARIS 2010 : LA GOUVERNANCE DANS SHAREPOINT ONLINE par ROMELARD Fabrice
Animé par: Emmanuel Bergerat et Damien Caro La session a démarré par un premier retour sur la situation de la la solution BPOS (Business Productivity OnLine Suite) et les possibilités commerciales associées ...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2010 : ADMINISTRATION SHAREPOINT 2010TECHDAYS PARIS 2010 : ADMINISTRATION SHAREPOINT 2010 par ROMELARD Fabrice
Animé par: Patrick Guimonet et Benoit Hamet Cette session traitera des différents points exigés durant les taches d'administration : Planification (architecture, hébergement, authentification, .) Opération e...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice [TECHDAYS 2010] #03 - WEB CONTENT MANAGEMENT SOUS SHAREPOINT 2010[TECHDAYS 2010] #03 - WEB CONTENT MANAGEMENT SOUS SHAREPOINT 2010 par pierre
Stephane Cordonnier de MCNext nous présente les fonctionnalités Web Content Management (WCM) sous SharePoint 2010. Qu'est-ce que le WCM ECM, GED, RM, WCM c'est quoi Plateforme SharePoint Versions SharePoint 2010 SharePoint Fondation...
Cliquez pour lire la suite de l'article par pierre [DESIGN PATTERNS] PARTIE 2: DIP: DEPENDENCY INVERSION PRINCIPLE[DESIGN PATTERNS] PARTIE 2: DIP: DEPENDENCY INVERSION PRINCIPLE par tja
C'est le dernier principe des principes du Design Orienté Objet (The Principles of Object Oriented Design) fondés par Robert C. Martin plus connu sous le pseudonyme d'Uncle Bob.
l'image empruntée de LosTechies.
Je ne traite pas les principes dans...
Cliquez pour lire la suite de l'article par tja
Forum
CAST DE POINTEURSCAST DE POINTEURS par zaraki21
Cliquez pour lire la suite par zaraki21 CARTE GOOGLECARTE GOOGLE par ja92
Cliquez pour lire la suite par ja92
Logiciels
DB-MAIN (9.1.0)DB-MAIN (9.1.0)DB-MAIN is a data-modeling and data-architecture tool. It is designed to help developers and anal... Cliquez pour télécharger DB-MAIN Xilisoft DPG Convertisseur (5.1.37.0120)XILISOFT DPG CONVERTISSEUR (5.1.37.0120)Xilisoft DPG Convertisseur offre aux fans de Nintendo DS une bonne solution leur permettant de dé... Cliquez pour télécharger Xilisoft DPG Convertisseur GraphicsGale (2.01.01)GRAPHICSGALE (2.01.01)GraphicsGale est un logiciel de PixelArt avec de nombreuse fonctionnalités permettant de réalisé ... Cliquez pour télécharger GraphicsGale Architecte 3D (Platinum 2010)ARCHITECTE 3D (PLATINUM 2010)Architecte 3D Platinium vous permet de concevoir facilement les plans votre future maison, de l'é... Cliquez pour télécharger Architecte 3D TeamViewer 5 (TeamViewer 5)TEAMVIEWER 5 (TEAMVIEWER 5)Dépanner un ami,expliquer une manipulation devient un jeu d'enfant.
Prise en main d'un autre ord... Cliquez pour télécharger TeamViewer 5
|