How to create an image in GDI + from Base64 encoding in C ++?

I have an application that is currently written in C # that can take a Base64 encoded string and turn it into an image (a TIFF image in this case) and vice versa. In C #, this is actually quite simple.

private byte[] ImageToByteArray(Image img) { MemoryStream ms = new MemoryStream(); img.Save(ms, System.Drawing.Imaging.ImageFormat.Tiff); return ms.ToArray(); } private Image byteArrayToImage(byte[] byteArrayIn) { MemoryStream ms = new MemoryStream(byteArrayIn); BinaryWriter bw = new BinaryWriter(ms); bw.Write(byteArrayIn); Image returnImage = Image.FromStream(ms, true, false); return returnImage; } // Convert Image into string byte[] imagebytes = ImageToByteArray(anImage); string Base64EncodedStringImage = Convert.ToBase64String(imagebytes); // Convert string into Image byte[] imagebytes = Convert.FromBase64String(Base64EncodedStringImage); Image anImage = byteArrayToImage(imagebytes); 

(and, now that I look at it, it can be simplified)

Now I have a business need to do this in C ++. I use GDI + for drawing graphics (only up to Windows), and I already have code for decode a string in C ++ (for another string). However, I stumble upon getting information into an Image object in GDI +.

At this point, I believe that I need

a) A way to convert this Base64-decoded string to an IStream to feed to an Image FromStream object

b) A way to convert a Base64 encoded string to IStream to feed a FromStream object to the Image object (so thereโ€™s a different code than I'm using now)

c) Some completely different ways that I don't think about.

My C ++ skills are very rusty and I am also spoiled by the managed .NET platform, so if I am on this incorrectly, I am open to suggestions.

UPDATE: In addition to the solution I posted below, I also figured out how to go the other way , if anyone needs it.

+4
source share
2 answers

This should be a two-step process. First, decode base64 to a clean binary (the bit you would have if you downloaded TIFF from a file). Google's first result for this looks pretty good.

Secondly, you will need to convert these bits to a Bitmap object. I followed this example when I had to load images from a resource table.

+3
source

OK, using the information from the Base64 decoder that I linked and the Ben Straub related example, I got it working

 using namespace Gdiplus; // Using GDI+ Graphics graphics(hdc); // Get this however you get this std::string encodedImage = "<Your Base64 Encoded String goes here>"; std::string decodedImage = base64_decode(encodedImage); // using the base64 // library I linked DWORD imageSize = decodedImage.length(); HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, imageSize); LPVOID pImage = ::GlobalLock(hMem); memcpy(pImage, decodedImage.c_str(), imageSize); IStream* pStream = NULL; ::CreateStreamOnHGlobal(hMem, FALSE, &pStream); Image image(pStream); graphics.DrawImage(&image, destRect); pStream->Release(); GlobalUnlock(hMem); GlobalFree(hMem); 

I am sure that it can be significantly improved, but it works.

+7
source

Source: https://habr.com/ru/post/1308492/


All Articles