简体   繁体   中英

Concatenating two base64 images in Javascript

Is it possible to do simple string concatenation to 'join' 2 base 64 encoded images together if the images have the same characteristics (width/height/color depth etc)?

eg

img1 w=100, h=200
img2 w=100, h=200

img1+img2 results in

img3 w=100, h=400

intuitively this feels like a stupid question since presumably the encoding includes headers containing meta data, but i don't know enough about base64 to know any better ;)

So far my preliminary tests have yielded broken results.

Thanks, Eli

since presumably the encoding includes headers containing meta data, but i don't know enough about base64 to know any better ;)

You're right: The content of a data: URI is the base64 encoded representation of the full image file data, including headers. You won't have any luck concatenating them that way.

The only way that could be possible on client side is using a Canvas . Here's a SO question that goes into that direction (it fetches an image into a canvas object).

I've come across this post on the far side of actually implementing a solution. You can in fact concatenate base64 strings. You just have to make sure that at encoding time (concatenation time in your case) you know the exact length of the two strings or you use a delimiter. I wrote a file format for combining files in base64 that the client then parses. Because it is for a canvas flash player called zero, the file format is called a '.zwf'. Here is the format. By the way, you can encode entire directories recursively with this format.

template

'<path>' <index> <length in characters> <encoding type (b64, b256, UTF8, etc.)> //HEADER these are entries in the zwf 
'<path>' <index> <length> <encoding>
'<path>' <index> <length> <encoding>
||||||||||                           //BREAK Indexes are relative to this
<file1><file2><file3>                //DATA All contents are here nose to tail

example.zwf

'hi.txt' 0 11 UTF8
'images/face.png' 11 1459 b64
||||||||||
Hello Worlddata:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4QBgRXhpZgAASUkqAAgAAAACADEBAgAHAAAAJgAAAGmHBAABAAAALgAAAAAAAABQaWNhc2EAAAMAAJAHAAQAAAAwMjIwAqAEAAEAAAAbAAAAA6AEAAEAAAAbAAAAAAAAAP/bAIQAAwICAwICAwMDAwQDAwQFCAUFBAQFCgcHBggMCgwMCwoLCw0OEhANDhEOCwsQFhARExQVFRUMDxcYFhQYEhQVFAEDBAQFBAUJBQUJFA0LDRQUFBQRFBQUFREUFBQVFBQUFBUPFREPExIQFBIQDxUVFBASERQUFRESFBUUEBIPFRIN/8AAEQgAGwAbAwERAAIRAQMRAf/EABgAAAMBAQAAAAAAAAAAAAAAAAYHCAUC/8QAMhAAAQMDAwEEBwkAAAAAAAAAAQIDBAURIQAGEjEIEyJBBwkVMlGhsRQWJTRhYoGCkf/EABoBAAIDAQEAAAAAAAAAAAAAAAYHAgMEAAX/xAAtEQABAwICCAYDAQAAAAAAAAABAAIDBBEhoQUTMUFRgbHwBhIUcZHhYcHRMv/aAAwDAQACEQMRAD8AX27Kq7SdqVqfDsZcaG881cXAUlBINvO1r21skPkYXDcs1OxsszI3YAkDNHPZt2VtuP6P5dRq/dKmlj7W87Kw86gkDmpSxdeTYm5z56UkomnnJldt2Y/y6d8Pp6eANhZs24c/wuN2bIRtipSPZ7TnsdwocaX7zTal8j3aFDFvCSB5XNsW0aaDqXSROglN3MPO30UuvENI2GZtTC2zHjlfHqOiGlRLqONEtkKeZB7zwrlMlwHFcUyWlNciLgXHXXTxa6J0YNrhSpZ/TzMltexTw7MVTplYrTEZqNAhpj0cxH2nXgEqfS6e9CED3lXQm4tfIuMjSt1DxK6OU/5J2nonayojfTtlhBxAOA7tzRX6bNxmS4xSkRkRwsNPPovdTbiErSEmxIvZebE9BnOiXQEIc+WbhYd5II8T1BayKn3G7r/rMpUlvPTRlZAHmUySfTDApiSmJ+JS7lKWWVjiD+5fQfM/pqD5mtVjIXPx3JydkTb1c3My3vKBW3KLUZUt1M5DDaFNOgLNykKBAUkfEXt1vg6XGlZJG1hFrg4g99+ybGhdW+haQSLYEeyLO1zvp70a7o2W1Snkz48mPNE1ySORfcStg8uQtZQ73qMeK1sY9nQmshjfJbBxGV79ckOeIiyeaOPe0HO1uh+UnWu0m3wHe0cpc8wmVj5o0Tip4tz+kIel4OUuxFmGywWfB4gMD4mx+usi2K5PV5KU7tSotrUot/ei3DkbWVFTyx/VP+asEEU7AJWg24rm1EtOSYnEX4LQ9ZRHahbx2azHabYZYocnu2m0BKUcn0FVgMZIB10wDPKxosLHD4UGvdIS95uTvUTTPzK/4+mqVYv/2Q%3D%3D

Using a .zwf you can concatenate arbitrary file types and reduce HTTP requests. You could package an entire website in a zwf.

JavaScript, in virtually any browser, can handle very large base64 strings. I've gone up to 2Mb in all modern browsers. My application doesn't require any larger so by all means find the limits.

On the client side, when the user requests a file, zero calls .slice() on the data section to retrieve it based on the index and length in the header. Slice is one of the fastest methods I know of.

The only trouble is that browsers

I think what you're suggesting has (at least) 2 problems:

  1. You haven't specified what format the images are in in the first place (eg GIF, JPG, PNG, etc.) Base64 is just a way of encoding binary data into text. Whether two images can be stitched together by simple bitstream concatenation would depend on the underlying binary format of the images.

  2. I don't know of any modern image formats that would support this kind of binary concatenation in the first place. Your initial concern (that images have meta-data somewhere in their binary representation that specifies image size, bit depth, etc.) is well founded.

I think the way you might want to go with this is to find a image manipulation library that allows you to take your binary images (once decoded from Base64), stitch them together as you see fit, and then re-encode the resulting, larger image as Base64.

If you're limited to JavaScript only, it looks like http://www.pixastic.com/lib/ is a nice image manipulation library but I can't determine whether it supports the kind of stitching you want. It's a place to start though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM