|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis article is intended to show ONE POSSIBLE way to load a bitmap/jpg/tiff/gif/png (whatever you can load with GDI+) and then convert it to bitmap/tiff/jpg/png (whatever you can save with GDI+) and save it to the memory. The article will NOT teach you anything useful about image compression, because it uses GDI+ to get the work done. Also please check out great tutorials here on CP on how to get GDI+ to run on your computer before trying this sample. This solution presented here is very simple and easy to understand but unfortunately it is not optimal. I guess the question is why do we need it then? The answer to this question is that sometimes if we are performing an operation in a program every once in a while but not very often, we are rather using simple solution that is not optimal than complicated which is optimal (Obviously, everybody has own preferences). Additionally, this article is intended for beginners, so you do not need to understand absolutely nothing about bitmaps and image compression in order to understand the code (I am not discouraging you from learning it when the time allows). BackgroundHonestly I did not use the code extensively. The code was created when I referenced MSDN for some function that I did not use for a while. But then I run across the function Using the codeWell, as you can see there is not much to it. There is single function that you can copy and paste into your code. But before you can use it, you must link and start up GDI+ in your application. Again, there are nice tutorials on how to do this, here on CP. // load image Image image(L"Nice.bmp"); // Create stream with 0 size IStream* pIStream = NULL; if(CreateStreamOnHGlobal(NULL, TRUE, (LPSTREAM*)&pIStream) != S_OK) { AfxMessageBox(_T("Failed to create stream on global memory!")); return; } // Get encoder class id for jpg compression // for other compressions use // image/bmp // image/jpeg // image/gif // image/tiff // image/png CLSID pngClsid; GetEncoderClsid(L"image/jpeg", &pngClsid); // Setup encoder parameters EncoderParameters encoderParameters; encoderParameters.Count = 1; encoderParameters.Parameter[0].Guid = EncoderQuality; encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong; encoderParameters.Parameter[0].NumberOfValues = 1; // setup compression level ULONG quality = 50; encoderParameters.Parameter[0].Value = &quality; // Save the image to the stream Status SaveStatus = image.Save(pIStream, &pngClsid, &encoderParameters); if(SaveStatus != Ok) { // this should free global memory used by the stream // according to MSDN pIStream->Release(); AfxMessageBox(_T("Failed to save to stream!")); return; } // get the size of the stream ULARGE_INTEGER ulnSize; LARGE_INTEGER lnOffset; lnOffset.QuadPart = 0; if(pIStream->Seek(lnOffset, STREAM_SEEK_END, &ulnSize) != S_OK) { pIStream->Release(); AfxMessageBox(_T("Failed to get the size of the stream!")); return; } // now move the pointer to the beginning of the file if(pIStream->Seek(lnOffset, STREAM_SEEK_SET, NULL) != S_OK) { pIStream->Release(); AfxMessageBox(_T("Failed to move the file pointer to " "the beginning of the stream!")); return; } // here you can do what ever you want /* 1. You can use global memory HGLOBAL hg; if(GetHGlobalFromStream(pIStream, &hg) = S_OK) ... use hg for something 2. Copy it into some other buffer char *pBuff = new char[ulnSize.QuadPart]; // Read the stream directly into the buffer ULONG ulBytesRead; if(pIStream->Read(pBuff, ulnSize.QuadPart, &ulBytesRead) != S_OK) { pIStream->Release(); return; } */ // I am going to save it to the file just so we can // load the jpg to a gfx program CFile fFile; if(fFile.Open(_T("test.jpg"), CFile::modeCreate | CFile::modeWrite)) { char *pBuff = new char[ulnSize.QuadPart]; // Read the stream directly into the buffer ULONG ulBytesRead; if(pIStream->Read(pBuff, ulnSize.QuadPart, &ulBytesRead) != S_OK) { pIStream->Release(); delete pBuff; return; } fFile.Write(pBuff, ulBytesRead); fFile.Close(); delete pBuff; } else AfxMessageBox(_T("Failed to save data to the disk!")); // Free memory used by the stream pIStream->Release(); The code is very straight forward. First I load the image, in this case Nice.bmp. Then I have to construct the ConclusionPlease contact me with any questions, suggestions etc. and I will try to answer as soon as I can. Also, English is my third language, so feel free to give me suggestions to improve my writing skills. Please have in mind that I am not a GDI+ expert, nor I am using it very often. Have Fun !
|
||||||||||||||||||||||