I was wondering about the best way to tackle this. I'm trying to save a user-drawn image on a HTML5 canvas to my database so I can retrieve it later.
I got as far as creating the base64 data string for the image with the following code, hooked to a simple button clickhandler:
var image_data = $("#drawing_canvas").get(0).toDataURL('image/png');
I was planning on saving that data to my database and then retrieving it later on with something like this:
var myImage = new Image();
myImage.src = imgData;
ctx.drawImage(myImage, 0, 0);
However, these base64 'strings' seem to contain a lot of data. I was wondering if there's a better way to save these images to my database? I have yet to figure out a way to save the actual image as a .png. I could get it to open as a png in a new browser tab, but that's where I'm stuck at the moment.
Or would it be fine to store these base64 data strings in my database (in, I suppose, a 'text' column)?
Thanks in advance.
You want to use a BLOB type. Here's what the MySQL docs say about it:
BLOB values are treated as binary strings (byte strings). They have no character set, and sorting and comparison are based on the numeric values of the bytes in column values. TEXT values are treated as nonbinary strings (character strings). They have a character set, and values are sorted and compared based on the collation of the character set.
http://dev.mysql.com/doc/refman/5.0/en/blob.html
Related
Description of the issue:
I have an Insert script contains the binary data (image file) which used to be stored in Mysql DB as a blob, and the requirement is to convert the blob data to base64 and store it in SQL Server. I tried inserting the blob data directly to SQL Server as Image and varbinary data type and converted them to base64, however, both methods failed to display the image on the web.
I tried exporting the image file from Mysql db and try to view it, but the format looks invalid.
I'm not sure what format the image file stored in Mysql DB and its hard to decode. Can anyone help me?
Sample file:
0xa15b8a9e56c2a7f9b56c4015a0eaf6abaf9f39575c028b39ffea32c35dad471522babf9f5abfeaea7eafaebafadf2d596
Where is the problem? MariaDB BLOB? SQL Server? Displaying Base64 as an image? Something else?
Here are some tips:
In MariaDB (at least) you can use UNHEX(some 8-bit data) as the expression to insert into a BLOB column.
In MariaDB (at least) you can use BASE64(some 8-bit data) to produce a text string that could be put into either TEXT or BLOB.
To display Base64 as an image in a <img> in HTML, you need to say that it is encoded that way. (The details are a bit obscure, but it works, and the string is part of the html.)
To display an image (from any of many locations), you need a separate program that runs in the web server, has the suitable "Header" and writes the binary (not Base64) bytes of the image. In this case, use, or example, <img src=foo.php?...> where foo.php uses its paramters ($_GET) to fetch the image (and, if neccesary, convert from Base64), then echo the Header the the image type and the binary of the image.
I have plenty of base64_encoded strings which I save in my MySQL DB. However, since base64_encoded strings are 33% larger, I would like to know how I can optimize my DB storage (Now I store my strings in a LONGTEXT field, but what about LONGBLOB or something similar?). So, how I can save my data (which is now base64 encoded) more optimized so I save storage space... (When selecting the value, I still have to be able to encode it base64 safely again).
Thanks
If you have 5.6.1 or later, FROM/TO_BASE64() are available in MySQL.
Base64 is plain ascii text. Storing base64 in a TEXT is no problem. No escaping is necessary since (I think) there are no naughty characters. But storing the result of FROM_BASE64 needs a BLOB (of some size).
So...
INSERT INTO t (myblob) VALUES ( FROM_BASE64('UmljayBKYW1lcw==') );
SELECT TO_BASE64(myblob) FROM t;
The FROM_BASE64 will reconstruct the original (pre-base64) data.
Even better would be to compress instead:
INSERT INTO t (myblob) VALUES ( COMPRESS('UmljayBKYW1lcw==') );
SELECT UNCOMPRESS(myblob) FROM t;
That way, you will (probably) get more than the 33% _if the original (pre-base64) data was compressible. If the original was a .jpg or some other already-compressed data, then you may as well use FROM_BASE64 instead of COMPRESS.
Using Flex (and HTTPService), I am loading data from an URL, data that is encoded with the GBK charset. A good example of such an URL is this one.
A browser gets that the data is in the GBK charset, and correctly displays the text using Chinese characters where they appear. However, Flex will hold the data in a different charset, and it happens to look like this:
({"q":"tes","p":false,"bs":"","s":["ÌØ˹À","ÌØÊâ·ûºÅ","test","ÌØÊâÉí·Ý","tesco","ÌØ˹ÀÆû³µ","ÌØÊÓÍø","ÌØÊâ·ûºÅͼ°¸´óȫ","testin","ÌØ˹ÀÆ۸ñ"]});
I need to correctly change the text to the same character string that the browsers display.
What I am already doing is using ByteArray, with the best result so far by using "iso-8859-1":
var convert:String;
var byte:ByteArray = new ByteArray();
byte.writeMultiByte(event.result as String, "iso-8859-1");
byte.position = 0;
convert = byte.readMultiByte(byte.bytesAvailable, "gbk");
This creates the following string, which is very close to the browser result but not entirely:
({"q":"tes","p":false,"bs":"","s":["特?拉","特殊符号","test","特殊身份","tesco","特?拉汽车","特视网","特殊符号?案大?","testin","特?拉????]});
Some characters are still replaced by "?" marks. And when I copy the browser result into Flex and print it, it gets displayed correctly so it is not a matter of unsupported characters in Flash trace or anything like that.
Interesting fact: Notepad++ gives the same close-but-not-quite result as the bytearray approach in Flex. Also in NP++, when converting the correct/expected string, from gbk to iso-8859-1, I am getting a slightly different string than the one Flex is getting from the URL:
({"q":"tes","p":false,"bs":"","s":["ÌØ˹À","ÌØÊâ·ûºÅ","test","ÌØÊâÉí·Ý","tesco","ÌØ˹ÀÆû³µ","ÌØÊÓÍø","ÌØÊâ·ûºÅͼ°¸´óÈ«","testin","ÌØ˹ÀÆû³µ¼Û¸ñ"]});
Seems to me that this string is the one that Flex should be getting, to have the ByteArray approach create the correct result (visible in browsers). So I see possible 3 causes for this:
Something is happening to the data coming from the URL to Flex, causing it to be slightly different (unlikely)
The received charset is not actually iso-8859-1, but another similar charset
I don't have a complete grasp of the difference between encoding and charset, so maybe this keeps me from understanding the problem.
Any help/idea would be greatly appreciated.
Thank you.
Managed to find the problem and solution, hope this will help anyone else in the future.
Turns out using HTTPService automatically converts the result into a String, which may compress some pair of bytes into single characters. That is why I was getting the first result (see up) instead of the third one. What I needed to do is get the result in binary form, and HTTPService does not have this type of resultFormat; however URLLoader does.
Replace HTTPService with URLLoader
Set the dataFormat property of the URLLoader to URLLoaderDataFormat.BINARY
After loading, the data property will return as a ByteArray. Tracing this byte array (or converting it into a String) will display the same result as the HTTPService is getting, which is still wrong, however in reality the byte array actually holds the correct data byte for byte (the length property of the byte array will be a bit larger than the size of the converted string).
So you can read the string from this bytearray, using the "gbk" charset:
byteArray.readMultyByte(byteArray.length, "gbk");
This returns the correct string, which the browser is also displaying.
I searched a lot, perhaps inefficiently, but I can not find information on how to scale the image stored in the database?
I'm inserting my image as
"0xffd8ffe110e94578696..."
after ussing unpack:
$data = file_get_contents($_FILES['image']['tmp_name']);
$data = unpack('H*',$data);
$data = '0x'.$data[1];
And then I can preview my image using base64_encode:
<img src="data:image/png;base64,/9j/4RDpRXhpZgAATU0AKgAAAAg...e6/9k=">
Probably informations above are unnecessary, becasue it's obvious how to send img to DB and how to preview that image. But maybe it helps you to understand me.
So is there any way to achieve that?
Scaling your image is not a function of your database system. Instead, it's a function of your host language.
You need to retrieve the image from the database in which you've stored its byte stream as a binary large object (blob). You then need to use some software or other to rescale it. This most likely requires decoding the byte stream, resampling the image, and encoding a byte stream for a new image.
You then can store it back into the database. Depending on what your application needs, you might choose to UPDATE the row with the original blob, or INSERT another row with the new blob.
I'd have some blob data such as:
0x3333332c2044e963617269652c20356520e9746167650d0a53742d4c617572656e7420285175e9626563292048344e20334d390d0a
that I'd like to convert to text because the new database has text field instead of blobs and now it makes trouble with some accentuated characters.
Is there somekind of blob to string converter somewhere?
Thanks a lot!
Try:
CONVERT(blobname USING latin1)
It depends on what the blob is. For example, I've dealt with some blobs that could be represented as basic XML files. Those would have been relatively easy to convert. However, I dealt with other blobs that were image files. If you tried to represent them as text you'd lose data.
What are in your blobs?
Create your new database with your export, once done create your text column on the table, update that using a CONVERT drop the old column, renaming the old one if required.
However if the data contains simple byte stream (that is, unstructured data, files, audio, video, whatever) and you need to represent them as pure ASCII you could change into a Base64 string.
If using phpmyadmin, tick the box that says "Dump binary columns in hexadecimal notation (for example, "abc" becomes 0x616263)" at the bottom of the export page.