J'ai écrit un code qui devrait normalement compresser grâce à la quantification vectorielle des images bitmaps, mais ça a pas l'air de marcher trop fort... Disons que le dictionnaire ne se crée pas correctement, si vous pouviez essayer de repérer les erreurs.
Merci d'avance.
#include <windows.h>
#include <time.h>
#include <fstream>
#include <vector>
#include <iostream>
using namespace std;
#define for if(1) for
///////////////////////////////////////////////////////////////////
struct SBlock
{
long vector[12];
short tableref;
long distance;
};
///////////////////////////////////////////////////////////////////
struct STable
{
long vector[12];
short nblock;
vector<short> blockref;
};
///////////////////////////////////////////////////////////////////
int CompressImage(char szLoadPath[400], char szSavePath[400], short Width, short Height,
short NVECTORTABLE, short NLOOPTABLE)
{
//Chargement du bitmap à compresser
cout << "Chargement du bitmap" << endl;
HDC hdcImage;
HBITMAP hbm;
hbm = (HBITMAP)LoadImage( NULL, szLoadPath, IMAGE_BITMAP, Width, Height,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if (hbm == NULL)
return 1;
hdcImage = CreateCompatibleDC(NULL);
SelectObject(hdcImage, hbm);
//Création des blocks 2*2 de vecteurs
cout << "Creation des blocks" << endl;
SBlock *block = new SBlock[(Width / 2) * (Height / 2)];
short nBlock = 0;
int pixelvalue;
for (short y = 0; y < Height - 1; y += 2)
{
for (short x = 0; x < Width - 1; x += 2)
{
short r, g, b;
pixelvalue = GetPixel(hdcImage, x, y);
r = (pixelvalue & 0xFF);
g = (pixelvalue & 0xFF00)>>8;
b = (pixelvalue & 0xFF0000)>>16;
block[nBlock].vector[0] = r;
block[nBlock].vector[1] = g;
block[nBlock].vector[2] = b;
pixelvalue = GetPixel(hdcImage, x+1, y);
r = (pixelvalue & 0xFF);
g = (pixelvalue & 0xFF00)>>8;
b = (pixelvalue & 0xFF0000)>>16;
block[nBlock].vector[3] = r;
block[nBlock].vector[4] = g;
block[nBlock].vector[5] = b;
pixelvalue = GetPixel(hdcImage, x, y+1);
r = (pixelvalue & 0xFF);
g = (pixelvalue & 0xFF00)>>8;
b = (pixelvalue & 0xFF0000)>>16;
block[nBlock].vector[6] = r;
block[nBlock].vector[7] = g;
block[nBlock].vector[8] = b;
pixelvalue = GetPixel(hdcImage, x+1, y+1);
r = (pixelvalue & 0xFF);
g = (pixelvalue & 0xFF00)>>8;
b = (pixelvalue & 0xFF0000)>>16;
block[nBlock].vector[9] = r;
block[nBlock].vector[10] = g;
block[nBlock].vector[11] = b;
nBlock++;
}
}
//Création de la table initiale générée aléatoirement à partir des blocks
cout << "Initialisation aleatoire de la table" << endl;
STable *table = new STable[NVECTORTABLE];
int randomblock = 0;
int randomplus = nBlock / NVECTORTABLE;
for (short i = 0; i < NVECTORTABLE; i++)
{
for (short y = 0; y < 12; y++)
table[i].vector[y]= block[randomblock].vector[y];
randomblock += randomplus - 1;
}
//Mise en référence de la table 0 pour tous les blocks
cout << "Initialisation des blocks" << endl;
for (short i = 0; i < nBlock; i++)
{
long distance = (table[0].vector[0] - block[i].vector[0]) * (table[0].vector[0] - block[i].vector[0]) +
(table[0].vector[1] - block[i].vector[1]) * (table[0].vector[1] - block[i].vector[1]) +
(table[0].vector[2] - block[i].vector[2]) * (table[0].vector[2] - block[i].vector[2]) +
(table[0].vector[3] - block[i].vector[3]) * (table[0].vector[3] - block[i].vector[3]) +
(table[0].vector[4] - block[i].vector[4]) * (table[0].vector[4] - block[i].vector[4]) +
(table[0].vector[5] - block[i].vector[5]) * (table[0].vector[5] - block[i].vector[5]) +
(table[0].vector[6] - block[i].vector[6]) * (table[0].vector[6] - block[i].vector[6]) +
(table[0].vector[7] - block[i].vector[7]) * (table[0].vector[7] - block[i].vector[7]) +
(table[0].vector[8] - block[i].vector[8]) * (table[0].vector[8] - block[i].vector[8]) +
(table[0].vector[9] - block[i].vector[9]) * (table[0].vector[9] - block[i].vector[9]) +
(table[0].vector[10] - block[i].vector[10]) * (table[0].vector[10] - block[i].vector[10]) +
(table[0].vector[11] - block[i].vector[11]) * (table[0].vector[11] - block[i].vector[11]);
block[i].tableref = 0;
block[i].distance = distance;
table[0].nblock++;
table[0].blockref.push_back(i);
}
//Mise au point de la table
cout << "Mise au point de la table" << endl;
for (short loop = 0; loop < NLOOPTABLE; loop++)
{
//Recherche de la meilleur table pour chaque block
cout << "1" << endl;
for (short i = 0; i < nBlock; i++)
for (short j = 0; j < NVECTORTABLE; j++)
{
long distance = (table[j].vector[0] - block[i].vector[0]) * (table[j].vector[0] - block[i].vector[0]) +
(table[j].vector[1] - block[i].vector[1]) * (table[j].vector[1] - block[i].vector[1]) +
(table[j].vector[2] - block[i].vector[2]) * (table[j].vector[2] - block[i].vector[2]) +
(table[j].vector[3] - block[i].vector[3]) * (table[j].vector[3] - block[i].vector[3]) +
(table[j].vector[4] - block[i].vector[4]) * (table[j].vector[4] - block[i].vector[4]) +
(table[j].vector[5] - block[i].vector[5]) * (table[j].vector[5] - block[i].vector[5]) +
(table[j].vector[6] - block[i].vector[6]) * (table[j].vector[6] - block[i].vector[6]) +
(table[j].vector[7] - block[i].vector[7]) * (table[j].vector[7] - block[i].vector[7]) +
(table[j].vector[8] - block[i].vector[8]) * (table[j].vector[8] - block[i].vector[8]) +
(table[j].vector[9] - block[i].vector[9]) * (table[j].vector[9] - block[i].vector[9]) +
(table[j].vector[10] - block[i].vector[10]) * (table[j].vector[10] - block[i].vector[10]) +
(table[j].vector[11] - block[i].vector[11]) * (table[j].vector[11] - block[i].vector[11]);
if (distance < block[i].distance)
{
for (short k = 0; k < table[block[i].tableref].nblock; k++)
{
if (table[block[i].tableref].blockref[k] == i)
{
table[block[i].tableref].nblock--;
table[block[i].tableref].blockref.erase(table[block
[i].tableref].blockref.begin() + i);
block[i].distance = distance;
block[i].tableref = j;
table[j].nblock++;
table[j].blockref.push_back(i);
break;
}
}
}
}
//Affinage de la table en calculant les isobarycentres des groupes de blocks
cout << "2"<< endl;
for (short i = 0; i < NVECTORTABLE; i++)
{
for (short j = 0; j < 12; j++)
{
double coord = 0;
for (short k = 0; k < table[i].nblock; k++)
coord += block[table[i].blockref[k]].vector[j];
coord = coord / table[i].nblock;
table[i].vector[j] = (long) coord;
}
}
//Mise à jour de la distance entre les blocks et la nouvelle table
cout << "3" << endl;
for (short i = 0; i <= nBlock; i++)
{
long distance = (table[block[i].tableref].vector[0] - block[i].vector[0]) * (table[block[i].tableref].vector[0] - block[i].vector[0]) +
(table[block[i].tableref].vector[1] - block[i].vector[1]) * (table[block[i].tableref].vector[1] - block[i].vector[1]) +
(table[block[i].tableref].vector[2] - block[i].vector[2]) * (table[block[i].tableref].vector[2] - block[i].vector[2]) +
(table[block[i].tableref].vector[3] - block[i].vector[3]) * (table[block[i].tableref].vector[3] - block[i].vector[3]) +
(table[block[i].tableref].vector[4] - block[i].vector[4]) * (table[block[i].tableref].vector[4] - block[i].vector[4]) +
(table[block[i].tableref].vector[5] - block[i].vector[5]) * (table[block[i].tableref].vector[5] - block[i].vector[5]) +
(table[block[i].tableref].vector[6] - block[i].vector[6]) * (table[block[i].tableref].vector[6] - block[i].vector[6]) +
(table[block[i].tableref].vector[7] - block[i].vector[7]) * (table[block[i].tableref].vector[7] - block[i].vector[7]) +
(table[block[i].tableref].vector[8] - block[i].vector[8]) * (table[block[i].tableref].vector[8] - block[i].vector[8]) +
(table[block[i].tableref].vector[9] - block[i].vector[9]) * (table[block[i].tableref].vector[9] - block[i].vector[9]) +
(table[block[i].tableref].vector[10] - block[i].vector[10]) * (table[block[i].tableref].vector[10] - block[i].vector[10]) +
(table[block[i].tableref].vector[11] - block[i].vector[11]) * (table[block[i].tableref].vector[11] - block[i].vector[11]);
block[i].distance = distance;
}
}
//Création de l'image compressée
cout << "Creation du fichier" << endl;
ofstream file(szSavePath);
file << Width << " ";
file << Height << " ";
file << nBlock << " ";
file << NVECTORTABLE;
for (short i = 0; i < NVECTORTABLE; i++)
{
file << " " << table[i].vector[0];
file << " " << table[i].vector[1];
file << " " << table[i].vector[2];
file << " " << table[i].vector[3];
file << " " << table[i].vector[4];
file << " " << table[i].vector[5];
file << " " << table[i].vector[6];
file << " " << table[i].vector[7];
file << " " << table[i].vector[8];
file << " " << table[i].vector[9];
file << " " << table[i].vector[10];
file << " " << table[i].vector[11];
}
for (short i = 0; i < nBlock; i++)
file << " " << block[i].tableref;
file << endl;
file.close();
return 0;
}
int main()
{
int last = GetTickCount();
int current;
int total;
cout << "Debut" << endl;
int x = CompressImage( "source.bmp",
"sortie.txt",
250, 300,
4, 2);
if (x)
cout << "Erreur pendant la compression";
current = GetTickCount();
total = current - last;
total = (total / 1000) / 60;
cout << "Temps mis pour compresser l'image: " << total << " minutes" << endl;
while(1)
{
}
return 0;
}