Obtenir la taille de jpeg de la mémoire (converti en utilisant GDI ++)

voix
4

Ceci est mon premier post ici. J'ai un problème. Je dois prendre un sceenshot du bureau, le convertir en jpeg, le stocker dans une mémoire tampon, puis le manipuler et l'envoyer sur Internet.

J'ai écrit le code pour le faire avec GetDC .... et GDI + pour convertir le HBITMAP au format JPEG. Le problème que j'ai maintenant que je ne connais pas la taille du jpeg qui a été enregistré dans le IStream. Voici une partie du code qui transforme le bitmap référencé par le HBITMAP hBackBitmap en jpeg et enregistrez-le dans pStream. Je dois savoir combien d'octets ont été écrits en pStream et comment je peux utiliser pStream (obtenir une poignée de PVOID):

Gdiplus::Bitmap bitmap(hBackBitmap, NULL);///loading the HBITMAP
CLSID clsid;
GetEncoderClsid(Limage/jpeg, &clsid);
HGLOBAL hGlobal = GlobalAlloc(GMEM_FIXED, nBlockSize) ;//allocating memory, the size of the current bitmap size. i'm over allocating but i don't think there is any way to get the exact ammount I need to allocate, is there?
if(!hGlobal)
    return;
IStream* pStream = NULL ;
if(CreateStreamOnHGlobal(hGlobal, TRUE, &pStream) != S_OK )
    return;
bitmap.Save(pStream, &clsid);

Ce que j'ai besoin est: 1. Trouvez la taille de jpeg, combien d'octets ont été écrits dans le flux 2. Comment utiliser le flux. Puis-je obtenir un PVOID pour les données en flux par exemple?

Je vous remercie.

Créé 07/07/2009 à 08:43
source utilisateur
Dans d'autres langues...                            


2 réponses

voix
5

Selon la CreateStreamOnHGlobal documentation, votre utilisation de celui - ci est incorrent. Citation:

Le contenu actuel du bloc de mémoire ne sont pas affectés par la création du nouvel objet de flux. Ainsi, vous pouvez utiliser cette fonction pour ouvrir un flux existant en mémoire. La taille initiale du courant est la taille de la poignée de mémoire retournée par la fonction GlobalSize.

Par conséquent, vous devez remplacer nBlockSize avec 0 à allouer un tampon de taille zéro. Comme le tampon de mémoire doit être mobile, vous aurez également besoin de remplacer GMEM_FIXED avec GMEM_MOVEABLE:

HGLOBAL gGlobal = GlobalAlloc(GMEM_MOVEABLE, 0);

Après avoir enregistré le flux, la taille résultante sera disponible

size_t size = GlobalSize(hGlobal);

Pour accéder aux données codées JPEG, vous devez utiliser GlobalLock pour obtenir un pointeur vers l'emplacement réel en mémoire.

Notez que les fonctions globales et locales sont marquées comme dépréciée et ne doivent pas être utilisés plus, mais je ne sais pas une meilleure mise en œuvre IStream pour vos besoins sans avoir à ramper la documentation MSDN. Peut-être que quelqu'un d'autre peut aider ici !?

Créé 07/07/2009 à 10:08
source utilisateur

voix
1

OK , j'ai trouvé ici la solution à ce problème: http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/6dfc2e62-e2d1-4be3-a93b-a7d97d3f8469

Je vais aussi mettre ici pour référence ultérieure. Pour connaître la taille qui a été écrit dans le flux, on peut utiliser la méthode Seek du flux. Pour avoir accès à la mémoire tampon, vous pouvez utiliser Lire.

   // Calculate reasonably safe buffer size
   int stride = 4 * ((image.GetWidth() + 3) / 4);
  size_t safeSize = stride * image.GetHeight() * 4 + sizeof(BITMAPINFOHEADER) +    sizeof(BITMAPFILEHEADER) + 256 * sizeof(RGBQUAD);
  HGLOBAL mem = GlobalAlloc(GHND, safeSize);
  assert(mem);

  // Create stream and save bitmap
  IStream* stream = 0;
  hr = CreateStreamOnHGlobal(mem, TRUE, &stream);
  assert(hr == S_OK);
  hr = image.Save(stream, Gdiplus::ImageFormatBMP);
  assert(hr == S_OK);

  // Allocate buffer for saved image
  LARGE_INTEGER seekPos = {0};
  ULARGE_INTEGER imageSize;
  hr = stream->Seek(seekPos, STREAM_SEEK_CUR, &imageSize);
  assert(hr == S_OK && imageSize.HighPart == 0);
  BYTE* buffer = new BYTE[imageSize.LowPart];

  // Fill buffer from stream
   hr = stream->Seek(seekPos, STREAM_SEEK_SET, 0);
   assert(hr == S_OK);
   hr = stream->Read(buffer, imageSize.LowPart, 0);
   assert(hr == S_OK);


   // Cleanup
  stream->Release();
  delete[] buffer;
  return 0;
Créé 07/07/2009 à 10:12
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more