IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Visual C++ Discussion :

vc++ & matrice & image


Sujet :

Visual C++

  1. #81
    Membre éclairé Avatar de meera
    Inscrit en
    Mai 2006
    Messages
    294
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 294
    Par défaut
    ok je la verifiée
    pour le buffer , franchement je sais rien sur lui,
    en lisant le code CImage.cpp de la bibliothque qu j'utilise, j'ai trouvé quq expression tl que:
    -m_nFileFormat = IMG_FORMAT_RLE;
    -if(BmInfo->bmiHeader.biCompression == BI_RLE8)
    -bSuccess = SaveRLE(hFile);
    je pense que cette methode est prédéfinit ds cette bibliothéque, mais je sais pas cmt je l'apelle

    voila un morceu de code CImage.cpp!!!!!!!!


    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
     
    // Image compressée RLE
    			int nCount;
    			BYTE cData1, cData2, cData3;
    			int x = nXBegin;
    			int y = nYBegin;
    			BOOL bBreak = FALSE;
    			while(ImgDatas<EndData && !bBreak)
    			{
    				nCount = *(ImgDatas++);
    				if(nCount & 0x80)
    				{
    					// Run-length packet
    					nCount = (nCount & 0x7F) + 1;
    					if(nCount>128)
    					{
    						GlobalUnlock(hNewDib);
    						GlobalFree(hNewDib);
    						return FALSE;
    					}
    					cData1 = *(ImgDatas++);
    					if(EnteteTGA->ImageType == 10)
    					{
    						cData2 = *(ImgDatas++);
    						cData3 = *(ImgDatas++);
    					}
    					for(int i=0; i<nCount && !bBreak; i++)
    					{
    						if(EnteteTGA->ImageType == 9)
    							lpBits[y*nScanWidth+x] = cData1;
    						else
    						{
    							lpBits[y*nScanWidth+3*x] = cData1;
    							lpBits[y*nScanWidth+3*x+1] = cData2;
    							lpBits[y*nScanWidth+3*x+2] = cData3;
    						}
    						x += nXStep;
    						if((nXStep<0 && x<=nXEnd) || (nXStep>0 && x>=nXEnd))
    						{
    							y += nYStep;
    							x = nXBegin;
    						}
    						if((nYStep<0 && y<=nYEnd) || (nYStep>0 && y>=nYEnd))
    							bBreak = TRUE;
    					}
    				}
    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
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
     
    // Sauvegarde du BMP sous format compressé RLE (8 bits seulement)
    //  !! les images en 4 bits sont codées en RLE 8
    BOOL CImage::SaveRLE(HANDLE hFile)
    {
    	if(GetBPP() != 8 && GetBPP() != 4)
    		return FALSE;
     
    	LPBITMAPINFOHEADER BmInfo=(LPBITMAPINFOHEADER)GlobalLock(m_hDib);			
    	int nColors = BmInfo->biClrUsed ? BmInfo->biClrUsed : 0x1FF & (1 << BmInfo->biBitCount);
    	int nScanWidth = WIDTHBYTES(BmInfo->biWidth * BmInfo->biBitCount);
     
    	// Header avec marque de signature
    	BITMAPFILEHEADER BmHeader;
    	memset(&BmHeader, 0, sizeof(BITMAPFILEHEADER));
    	BmHeader.bfType=FORMAT_BMP;
    	BmHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
    		+nColors*sizeof(RGBQUAD);
    	BmHeader.bfSize=BmHeader.bfOffBits+nScanWidth*BmInfo->biHeight;
     
    	// Ecriture du Header sur disque
    	if(!WriteSaveBuffer(hFile, &BmHeader, sizeof(BITMAPFILEHEADER)))
    	{
    		GlobalUnlock(m_hDib);
    		return FALSE;
    	}
     
    	// On change le marqueur de compression
    	BmInfo->biCompression = BmInfo->biBitCount==8 ? BI_RLE8 : BI_RLE4;
     
    	// Ecriture du BitmapInfo sur disque sur disque + couleurs
    	if(!WriteSaveBuffer(hFile, BmInfo, sizeof(BITMAPINFOHEADER)
    		+nColors*sizeof(RGBQUAD)))
    	{
    		GlobalUnlock(m_hDib);
    		return FALSE;
    	}
     
    	// On Remet le marqueur de compression à BI_RGB
    	BmInfo->biCompression = BI_RGB;
     
    	// Détermination de la position des bits (source)
    	BYTE* lpBits=(BYTE*)BmInfo+sizeof(BITMAPINFOHEADER)
    		+nColors*sizeof(RGBQUAD);
     
    	BYTE buffer[4];
    	BYTE first;
    	BYTE first2;
    	int nCount;
     
    	// Encodage des lignes
    	for(int y=0; y<BmInfo->biHeight; y++)
    	{
    		if(BmInfo->biBitCount==8) // en RLE8
    		{
    			for(int x=0; x<BmInfo->biWidth; )
    			{
    				first=lpBits[x];
    				nCount=1;
    				while(lpBits[++x]==first && x<BmInfo->biWidth && nCount<0xFE)
    					nCount++;
     
    				if(nCount == 1)
    				{
    					int nDummy = 1;
    					while(x+nDummy<=BmInfo->biWidth
    							&& lpBits[x+nDummy]!=lpBits[x+nDummy-1]
    							&& nDummy<0xFE)
    						nDummy++;
    					x--;
    					if(nDummy<3)
    					{
    						for(int i=0; i<nDummy; i++)
    						{
    							buffer[0]=1;
    							buffer[1]=lpBits[x++];
    							if(!WriteSaveBuffer(hFile, &buffer, 2L))
    							{
    								GlobalUnlock(m_hDib);
    								return FALSE;
    							}
    						}
    					}
    					else
    					{
    						buffer[0]=0;
    						buffer[1]=(BYTE)nDummy;
    						if(!WriteSaveBuffer(hFile, &buffer, 2L))
    						{
    							GlobalUnlock(m_hDib);
    							return FALSE;
    						}
    						for(int i=0; i<nDummy; i++)
    						{
    							if(!WriteSaveBuffer(hFile, &lpBits[x++]))
    							{
    								GlobalUnlock(m_hDib);
    								return FALSE;
    							}
    						}
    						if(nDummy & 1)
    						{
    							buffer[0]=0;
    							WriteSaveBuffer(hFile, &buffer);
    						}
    					}
    				}
    				else
    				{
    					buffer[0]=nCount;
    					buffer[1]=first;
    					if(!WriteSaveBuffer(hFile, &buffer, 2L))
    					{
    						GlobalUnlock(m_hDib);
    						return FALSE;
    					}
    				}
    			}
    		}
    		else // en RLE4
    		{
    			int nFirstX;
    			for(int x=0; x<BmInfo->biWidth; )
    			{
    				nCount=2;
    				nFirstX = x;
    				first=(BYTE)GetPixel(x++, y, BmInfo);
    				if(x++<BmInfo->biWidth)
    				{
    					--x;
    					first2=(BYTE)GetPixel(x, y, BmInfo);
    					while(x++<BmInfo->biWidth && nCount<0xFC)
    					{
    						if(!(nCount & 1))
    						{
    							BYTE cPixCol = NULL;
    							if(x<BmInfo->biWidth)
    								cPixCol = (BYTE)GetPixel(x, y, BmInfo);
    							if(cPixCol!=first)
    								break;
    							else
    								nCount++;
    						}
    						else
    						{
    							BYTE cPixCol = NULL;
    							if(x<BmInfo->biWidth)
    								cPixCol = (BYTE)GetPixel(x, y, BmInfo);
    							if(cPixCol!=first2)
    								break;
    							else
    								nCount++;
    						}
    					}
    				}
     
    				if(nCount < 4)
    				{
    					int nDummy = 0;
    					x-=nCount;
    					while(x+nDummy<BmInfo->biWidth && nDummy<0xFC)
    					{
    						BOOL bFlag1=FALSE;
    						BYTE cPixel1 = 0;
    						BYTE cPixel2 = 0;
    						if(x+nDummy+2 < BmInfo->biWidth)
    						{
    							cPixel1 = (BYTE)GetPixel(x+nDummy, y, BmInfo);
    							cPixel2 = (BYTE)GetPixel(x+nDummy+2, y, BmInfo);
    							if(cPixel1 == cPixel2)
    								bFlag1=TRUE;
    						}
    						BOOL bFlag2=FALSE;
    						cPixel1 = 0;
    						cPixel2 = 0;
    						if(x+nDummy+3 < BmInfo->biWidth)
    						{
    							cPixel1 = (BYTE)GetPixel(x+nDummy+1, y, BmInfo);
    							cPixel2 = (BYTE)GetPixel(x+nDummy+3, y, BmInfo);
    							if(cPixel1 == cPixel2)
    								bFlag2=TRUE;
    						}
    						if(bFlag1 && bFlag2)
    							break;
    						else
    							nDummy+=2;
    					}
    					if(x+nDummy>=BmInfo->biWidth)
    						nDummy=BmInfo->biWidth-x;
    					if(nDummy<3)
    					{
    						buffer[0]=nDummy;
    						if(x<BmInfo->biWidth)
    							buffer[1]=(BYTE)GetPixel(x++, y, BmInfo)<<4;
    						else
    							x++;
    						if(x<BmInfo->biWidth)
    							buffer[1] |= (BYTE)GetPixel(x++, y, BmInfo);
    						else
    							x++;				
    						if(!WriteSaveBuffer(hFile, &buffer, 2L))
    						{
    							GlobalUnlock(m_hDib);
    							return FALSE;
    						}
    					}
    					else
    					{
    						buffer[0]=0;
    						buffer[1]=(BYTE)nDummy;
    						if(!WriteSaveBuffer(hFile, &buffer, 2L))
    						{
    							GlobalUnlock(m_hDib);
    							return FALSE;
    						}
    						for(int i=0; i<nDummy; i+=2)
    						{
    							if(x<BmInfo->biWidth)
    								buffer[0]=(BYTE)GetPixel(x++, y, BmInfo)<<4;
    							else
    								x++;
    							if(x<BmInfo->biWidth)
    								buffer[0] |= (BYTE)GetPixel(x++, y, BmInfo);
    							else
    								x++;
    							if(!WriteSaveBuffer(hFile, &buffer))
    							{
    								GlobalUnlock(m_hDib);
    								return FALSE;
    							}
    						}
    						if((nDummy+1) & 2)
    						{
    							buffer[0]=0;
    							WriteSaveBuffer(hFile, &buffer);
    						}
    					}
    				}
    				else
    				{
    					if(nFirstX+nCount>=BmInfo->biWidth)
    						nCount=BmInfo->biWidth-nFirstX;
    					buffer[0]=nCount;
    					buffer[1]=first<<4 | first2;
    					if(!WriteSaveBuffer(hFile, &buffer, 2L))
    					{
    						GlobalUnlock(m_hDib);
    						return FALSE;
    					}
    				}
    			}
    		}
    		// Marque de fin de ligne
    		buffer[0]=buffer[1]=0;
    		if(!WriteSaveBuffer(hFile, &buffer, 2L))
    		{
    			GlobalUnlock(m_hDib);
    			return FALSE;
    		}
    		lpBits+=nScanWidth;
    	}
     
    	// Marque de fin de bitmap
    	buffer[0]=0;
    	buffer[1]=1;
    	if(!WriteSaveBuffer(hFile, &buffer, 2L))
    	{
    		GlobalUnlock(m_hDib);
    		return FALSE;
    	}
     
    	// Terminé sans encombre
    	GlobalUnlock(m_hDib);
    	return TRUE;
    }

  2. #82
    Membre éclairé Avatar de meera
    Inscrit en
    Mai 2006
    Messages
    294
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 294
    Par défaut
    je le corrige
    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
     
    void generation_mat_zigzag(
     
    BYTE  eMatrice[8][8],		//[in] Matrice  à lire
     int x,                    //[in] Coordonnée X de la matrice 8*8
     int y,						//[in] Coordonnée Y de la matrice 8*8
     BYTE tab64[64]
     
     )
    {	
    	int ww=0,i;
     
      int max=8;
     
    while (ww<64) 
    {
     
      for (x=0; x<=max; x++)
      {
        for (y=0; y<=x; y++) 
     
    	{
    		if   (x%2==1)
     
     
    			tab64[ww]=	eMatrice[y][x-y];
     
    		else
     
    			tab64[ww]=	eMatrice[x-y][y];
     
    		}
    	}
      ww++;
      } 
     
    }

  3. #83
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    J'ignore si ta fonction est bonne, j'ai un peu de mal.

    Pour le BI_RLE, tu oublies: C'est du RLE pur, qui ne passe pas par une DCT.

    Quand à un "buffer" dans le cas présent, c'est une zone mémoire, tout simplement...
    Ta zone de 64 octets en est un, par exemple...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #84
    Membre éclairé Avatar de meera
    Inscrit en
    Mai 2006
    Messages
    294
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 294
    Par défaut
    merci pour tes explication

    non ussi j'ai trouvé par exemple: ( ds jpeglib.h et tiffio.h)
    -struct jpeg_inverse_dct { long dummy; };
    -#define TIFFTAG_JPEGDCTABLES
    -int (*coef_bits)[DCTSIZE2];
    ...
    mais j'ai trouvé l'algorithme
    ignorant ça , je les reprogramme à la main

    ok je vais essaie d voir la compression RLE
    puis Huffman et de les stoker ds un buffer

  5. #85
    Membre éclairé Avatar de meera
    Inscrit en
    Mai 2006
    Messages
    294
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 294
    Par défaut
    Citation Envoyé par meera
    merci pour tes explication

    non ussi j'ai trouvé par exemple: ( ds jpeglib.h et tiffio.h)
    -struct jpeg_inverse_dct { long dummy; };
    -#define TIFFTAG_JPEGDCTABLES
    -int (*coef_bits)[DCTSIZE2];
    ...
    mais j'ai pas trouvé l'algorithme
    ignorant ça , je les reprogramme à la main

    ok je vais essaie d voir la compression RLE
    puis Huffman et de les stoker ds un buffer

  6. #86
    Membre éclairé Avatar de meera
    Inscrit en
    Mai 2006
    Messages
    294
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 294
    Par défaut
    j'ai trouvé cette algorithme de RLE,
    ce site décrit l'algorithme RLE
    http://translate.google.com/translat...l%3Dfr%26lr%3D

    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
     
     
    int compressionRLE(char tab[],char tabcompresse[]) 
    { 
        int i,nbrepet=1,position=0,j=0; 
     
            for (i=0;i<NB_CARACTERES_MAX;i++) 
            { 
                nbrepet=1;     
                if (tab[i]==tab[i+1])             /*teste si les valeurs qui se suivent*/ 
                {                             /*sont identiques*/ 
     
                    while (tab[i]==tab[i+1]) /*compte le nombre de valeurs identiques*/ 
                    {                 /*se suivant*/ 
                                nbrepet=nbrepet+1; 
                                i++; 
                            } 
                                                 /*écrit les données de tabcompresse*/ 
                            tabcompresse[position]='$';     
                            tabcompresse[position+1]=(char)nbrepet+'0'; 
                            tabcompresse[position+2]=tab[i]; 
     
                            position=position+3; /*positionnement 3 cases aprés sur tabcompresse*/ 
                    } 
     
                else 
                    { 
                                /*si les valeurs se suivant dans tab ne sont pas identiques*/ 
                        tabcompresse[position]=tab[i];    /*écrit la valeur unique dans*/ 
                        position=position+1;            /* tabcompresse*/ 
                    } 
            } 
    }

  7. #87
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Je ne connais pas assez pour me plonger là-dedans.

    Déjà, essaie de faire marcher l'enregistrement non-compressé. N'essaie de compresser que lorsque tout le reste marchera.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #88
    Membre éclairé Avatar de meera
    Inscrit en
    Mai 2006
    Messages
    294
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 294
    Par défaut
    moi je fais l'exécution, tout marche ( 0 erreurs),ça de coté informatique
    par contre pour voir si tt ce quon a fait marche bien,il faut terminer tt l'algorithme et voir si on a arrivé à afficher une image compressé

  9. #89
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ben, pour pouvoir l'afficher, il faut
    • Soit enregistrer l'image au format JPEG (que je ne connais pas)
    • Soit faire l'algorithme inverse pour retransformer les données compressées en bitmap.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #90
    Membre éclairé Avatar de meera
    Inscrit en
    Mai 2006
    Messages
    294
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 294
    Par défaut
    oui je pense qu'il faut enregistrer l'image au format Jpeg, pour pouvoir l'affiché compressée
    sinon, (si on fait la decompression) , on n'affiche pas l'image compressée) ,on reterouvenotre image source
    moi meme je sais pas cmt l'enregistrer en ce format
    j'ai trouvé c code ds la librairie que j'utilise mais j'ai pas comprs grandes choses:
    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
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
     
    // Sauvegarde d'une image au format JPEG
    BOOL CImage::SaveJPEG(HANDLE hFile, int nQuality)
    {
    	if(!m_hDib)
    		return FALSE;
     
    	BOOL bGrayScale = FALSE;
     
    	// Vérification qu'il s'agit bien d'une image en 256 NG ou 24 bits
    	LPBITMAPINFO bi = (LPBITMAPINFO)GlobalLock(m_hDib);
     
    	if(bi->bmiHeader.biBitCount<8)
    	{
    		GlobalUnlock(m_hDib);
    		return FALSE;
    	}
     
    	int nColors = bi->bmiHeader.biClrUsed ? bi->bmiHeader.biClrUsed : 0x1FF & (1 << bi->bmiHeader.biBitCount);
    	if(bi->bmiHeader.biBitCount!=24)
    	{
    		bGrayScale = TRUE;
    		for(int i=0; i<nColors; i++)
    			if(bi->bmiColors[i].rgbRed!=bi->bmiColors[i].rgbGreen
    				|| bi->bmiColors[i].rgbRed !=bi->bmiColors[i].rgbBlue)
    			{
    				// Image en couleur avec palettes -> pas supporté
    				GlobalUnlock(m_hDib);
    				return FALSE;
    			}
    	}
     
    	int nLineSize = bi->bmiHeader.biWidth*(bGrayScale?1:3);
    	BYTE* pScanLine = (BYTE*)malloc(nLineSize);
    	if(!pScanLine)
    	{
    		GlobalUnlock(m_hDib);
    		return FALSE;
    	}
     
    	jpeg_compress_struct cinfo;
    	jpeg_error_mgr jerr;
     
    	cinfo.err = jpeg_std_error(&jerr);
    	jerr.error_exit = CImageJpegErrorExit;  // Register custom error manager.
     
    	typedef struct
    	{
    		void* pBuffer;
    		HANDLE hFile;
    	} JPegData;
     
    	JPegData JData;
    	JData.pBuffer = m_LoadBuffer;
    	JData.hFile = hFile;
     
    	try
    	{
    		jpeg_create_compress(&cinfo);
     
    		// Specify data destination
    		jpeg_destination_mgr dest;
    		dest.next_output_byte = (JOCTET *)m_LoadBuffer;
    		dest.free_in_buffer = SIZE_SAVE_BUFFER-4;
    		dest.init_destination = CImageJpegInitDest;
    		dest.empty_output_buffer = CImageJpegEmptyOutputBuffer;
    		dest.term_destination = CImageJpegTermDest;
    		cinfo.dest = &dest;
    		cinfo.client_data = &JData;
     
    		// Spécifications de l'image
    		cinfo.image_width = bi->bmiHeader.biWidth;
    		cinfo.image_height = bi->bmiHeader.biHeight;
    		cinfo.input_components = bGrayScale ? 1 : 3;
    		cinfo.in_color_space = bGrayScale ? JCS_GRAYSCALE : JCS_RGB;
    		jpeg_set_defaults(&cinfo);
     
    		// Affinage des paramètres de sortie
    		jpeg_set_quality(&cinfo, nQuality, TRUE);
    		cinfo.dct_method = JDCT_ISLOW;
    		cinfo.optimize_coding = TRUE;
    		cinfo.density_unit = 1;
    		cinfo.X_density = (int)PPM2DPI(bi->bmiHeader.biXPelsPerMeter);
    		cinfo.Y_density = (int)PPM2DPI(bi->bmiHeader.biYPelsPerMeter);
     
    		// Start compressor
    		jpeg_start_compress(&cinfo, TRUE);
     
    		// Ecriture successive des lignes
    		int nScanWidth = WIDTHBYTES(bi->bmiHeader.biWidth * bi->bmiHeader.biBitCount);
    		BYTE* pSrcLine = (BYTE*)bi+bi->bmiHeader.biSize+nColors*sizeof(RGBQUAD)
    			+nScanWidth*(bi->bmiHeader.biHeight-1);
    		while(cinfo.next_scanline < cinfo.image_height)
    		{
    			memcpy(pScanLine, pSrcLine, nLineSize);
    			if(bGrayScale)
    				for(int i=0; i<nLineSize; i++)
    					pScanLine[i] = bi->bmiColors[pScanLine[i]].rgbRed;
    			else
    			{
    				BYTE cDummy;
    				for(int i=0; i<nLineSize; i+=3)
    				{
    					cDummy = *(pScanLine+i);
    					*(pScanLine+i) = *(pScanLine+i+2);
    					*(pScanLine+i+2) = cDummy;
    				}
    			}
    			jpeg_write_scanlines(&cinfo, &pScanLine, 1);
    			pSrcLine -= nScanWidth;
    		}
     
    		// Finish compression
    		jpeg_finish_compress(&cinfo);
     
    		// Release JPEG decompression object
    		jpeg_destroy_compress(&cinfo);
     
    		free(pScanLine);
    		GlobalUnlock(m_hDib);
     
    		return TRUE;
    	}
    	catch(...)
    	{
    		jpeg_abort_compress(&cinfo);
    		GlobalUnlock(m_hDib);
    		free(pScanLine);
    		return FALSE;
    	}
    }
     
    // Init de la destination JPEG -> ne fait rien
    METHODDEF(void) CImageJpegInitDest(j_compress_ptr cinfo)
    {
    }
     
    // Ecrit le buffer de sauvegarde sur disque
    METHODDEF(boolean) CImageJpegEmptyOutputBuffer(j_compress_ptr cinfo)
    {
    	typedef struct
    	{
    		void* pBuffer;
    		HANDLE hFile;
    	} JPegData;
    	DWORD dwByteWrite;
     
    	JPegData* JData = (JPegData*)cinfo->client_data;
    	WriteFile(JData->hFile, JData->pBuffer, SIZE_SAVE_BUFFER-4,
    		&dwByteWrite, NULL);
    	memset(JData->pBuffer, 0, SIZE_SAVE_BUFFER);
    	cinfo->dest->next_output_byte = (JOCTET *)JData->pBuffer;
    	cinfo->dest->free_in_buffer = SIZE_SAVE_BUFFER-4;
     
    	return TRUE;
    }
     
    // Termine source ou destination JPeg -> ne fait rien
    METHODDEF(void) CImageJpegTermDest(j_compress_ptr cinfo)
    {
    	typedef struct
    	{
    		void* pBuffer;
    		HANDLE hFile;
    	} JPegData;
    	DWORD dwByteWrite;
     
    	JPegData* JData = (JPegData*)cinfo->client_data;
    	int nSize = (int)((BYTE*)cinfo->dest->next_output_byte - (BYTE*)JData->pBuffer);
    	if(nSize<1 || nSize>SIZE_SAVE_BUFFER-4)
    		return;
    	WriteFile(JData->hFile, JData->pBuffer, nSize, &dwByteWrite, NULL);
    }
    #endif  // CIMAGE_USE_JPEG

  11. #91
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ce code utilise GDI+ qui s'occupe de faire la conversion. Ici, c'est GDI+ qui fait la DCT et tout le reste...

    Et franchement, je pense que ce serait plus facile de faire la décompression soi-même que d'arriver à faire "rentrer" les données qu'on produit dans du JPEG...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #92
    Membre éclairé Avatar de meera
    Inscrit en
    Mai 2006
    Messages
    294
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 294
    Par défaut
    oui en lisant le code , je trouve que la compression Jpeg st déja integré ds cetet bibliothéque( bloc 8*8, DCT, quatification, RLE, Huffman,.....)
    mais malheureusement je sais pas cmt je les appelle ds mon projet( CProjetView.cpp)
    pour cela, j'ai préferé de reprogramme cette methode à la main

  13. #93
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Je n'ai jamais programmé avec GDI+, mais si tu veux créer une image .JPG, tu auras plus vite fait d'apprendre à utiliser GDI+ que d'apprendre le format JFIF (JPEG File Interchange Format) pour écrire dedans...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #94
    Membre éclairé Avatar de meera
    Inscrit en
    Mai 2006
    Messages
    294
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 294
    Par défaut
    ah je vais essaier
    malgré que c la 1ere fois que j'entend GDI+

    svp concernat un question que j'avais te posé precédament concernant commet je génera une marque( une marque c'est une matrice de la meme dimension que l'image que je vais choisit rempli par des valeurs pseudo aléatoire entre 0 et 1)
    je vx par ex quand je clickk sur un boutton ds le menu "marque" j'affiche cette matrice
    car apres je l'ajout à mon image source pour obrenir enfin une image tatouée

    tu m'as écrius cette fonction:
    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
     
    ///////////////////////////////////////////////////////////////////////////
    //////////////****** Fonction qui calcul le random******////////////
    /////////////////////////////////////////////////////////////////////////
    void MemRandom(void *pVoid, size_t size)
    {
    	#ifdef __cplusplus
    	char * const pMem = static_cast< char * >(pVoid);
    	#else
    	char * const pMem = pVoid;
    	#endif
     
    	size_t i;
    	for(i=0 ; i<size ; i++)
    	{
    		pMem[i] = (char)(rand() >> 7); //Si RAND_MAX est bien >= 32767
    	}
    }
    mais cette fonction prends en entrée une image n'est ce pas!!!
    car quand je fais appele de cette fonction
    lors de l'exécution ,il me demande de choisir une image puis quand je click sur le boutton marque l'image devient tt noir
    donc je dis afficher la marque sans tenir compte d'une image !!!!!!!

  15. #95
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Tu ne m'as jamais parlé de "marque"!! Tu m'as juste parlé de générer une image aléatoirement!
    Et la fonction prenait juste l'adresse des BitmapBits, dans lesquels elle écrivait son image aléatoire en sortie.

    Que cherches-tu à faire exactement ? Une Watermark sur l'image?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #96
    Membre éclairé Avatar de meera
    Inscrit en
    Mai 2006
    Messages
    294
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 294
    Par défaut
    oui mon sujet n effet c'est le tatouage des images numérique( watermarking)
    et l'algorithme de la compression Jpeg qui j'etais entrani de resoudre c'est un type des attaques qui peuvent subir une image tatouée

    mnt je vx savoir comment obtenir une marque par exemple
    car mon algorithme consiste à prendre une image appliqué la DCt sur elle , puis ajjouter la marque et applique l(innverse de la DCT et hup l'image devient tatouée

    citation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Insertion dans le domaine DCT :
    Cox et al. [13] proposent une méthode qui utilise la transformée en cosinus discrète (DCT ) pour insérer la marque dans l’image. Ils appliquent la DCT à toute l’image et insèrentla signature dans les basses fréquences, c’est à dire dans les composantes les plussignificatives. Ils modifient les μ fréquences de plus grande amplitude, exceptée lacomposante continue, suivant l’une des formules suivantes :
    . v’i = vi + a.xi
    . v’i = vi.(1 + a.xi)
    . v’i = vi.ea.xi
    avec :
    v’i : coefficient DCT de l’image marquée
    vi : coefficient DCT de l’image originale
    a : coefficient d’invisibilité
    xi : coefficient réel issu d’une distribution gaussienne centrée normée
    L’extraction se fait en inversant le processus d’insertion et en utilisant l’image
    originale pour retrouver la marque. La suite x’i extraite est comparée à la suite xi par un calculde corrélation. La décision est de type « tout ou rien ».

  17. #97
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ils ne disent pas ce qu'est i...

    Et les coefficients générés aléatoirement doivent être enregistrés quelque part, sinon la watermark invisible ne sert à rien...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  18. #98
    Membre éclairé Avatar de meera
    Inscrit en
    Mai 2006
    Messages
    294
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 294
    Par défaut
    d'aprés ce que je compris de la citation c est de :
    - prendre une image
    - appliquer DCT sut tt image-
    - ajouter la marque
    ( n utilisant l'une des formules sivantes :
    . v’i = vi + a.xi
    . v’i = vi.(1 + a.xi)
    . v’i = vi.ea.xi
    avec :
    v’i : coefficient DCT de l’image marquée
    vi : coefficient DCT de l’image originale
    a : coefficient d’invisibilité
    xi : coefficient réel issu d’une séquence aléatoire)
    par exemlpe si on choisit la premiére formule:
    vi les cofficient DCT qu'on calculé et xi c'est une génération aléatoire de la méme taille que l'image source , a coefficient de l'invisibilité

    mais d'aprés la citation:
    Ils appliquent la DCT à toute l’image et insèrent
    la signature dans les basses fréquences, c’est à dire dans les composantes les plus
    significatives. Ils modifient les μ fréquences de plus grande amplitude, exceptée la
    composante continue,

  19. #99
    Membre éclairé Avatar de meera
    Inscrit en
    Mai 2006
    Messages
    294
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 294
    Par défaut
    svp pour remplir une matrice par de valeurs aléatoires entre o et 1 est ce que la fonctio random () marche en vc++
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     void generation_random( BYTE matrand[8][8])
    {
     
    	for (int  i=0; i<8; i++)
    	{
    		for (int j=0;j<8;j++)
    		{
    			materand[i][j]=random();
    		}
    	}
    }

  20. #100
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Euh... Pourquoi veux-tu toujours remplir une matrice, alors qu'il faut interagir avec une matrice existante?

    Et pour le random, c'est inscrit dans la FAQ.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. [cat] Concaténation de matrices d'images
    Par Mamadou1 dans le forum Images
    Réponses: 1
    Dernier message: 20/10/2007, 20h29
  2. Réponses: 43
    Dernier message: 14/06/2007, 17h56
  3. Transformer une matrice à une image
    Par stiko83 dans le forum C++
    Réponses: 24
    Dernier message: 01/08/2006, 23h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo