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 / Exemple :
/*-----------------------------------------------------------------------------------------------*
//
// 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)
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.