I was reading from a few tutorials on how to upload my image into the DB as binary opposed to putting them on the server itself, well I got it to work like this:
PHP:
$image = chunk_split(base64_encode(file_get_contents($tmpfile)));
mysql_query("INSERT INTO images (`img_location`, `caption`, `user`, `genre`, `when`) VALUES ('$image', '$caption', '$id', '$genre', '$when')");
My issue is how do you now pull it from the database, I've read several ways of doing it, tried them all, can't figure it out, I'm not getting a MySQL error, here's how I'm trying it:
$get_pics = mysql_query("SELECT * FROM images WHERE user='$id' ");
while($get_pics2 = mysql_fetch_array($get_pics))
{
$sixfour_enc = base64_decode($get_pics2['img_location']);
$new .= "<img src=\"".$sixfour_enc."\" >";
}
This works... kind of, what's happening is that it's printing out raw binary in the IMG tag.
How do I get this to compile to a readble image again? Also, is storing the images in the database stupid? Should I just do what I usually do and store them on the server?
Thank you
-mike
You can store images in your database if you want to (though there's nothing wrong with just storing them as files either, choose whatever is appropriate in your situation), but store the raw binary data in a BLOB (i.e. don't encode it with base64). You can embed the binary data you get from file_get_contents in your query directly, provided you use the proper escape function (mysql_real_escape_string in your case) first.
As for the outputting of the image, you can do it the way you're doing it right now, but you'll have to output it base64-encoded and with a data URI scheme like this:
echo '<img alt="embedded image" src="data:image/png;base64,' . chunk_split(base64_encode($get_pics2['img_location'])) . '">';
Note that there are some advantages and disadvantages of embedded image data. Some important disadvantages to be aware of are the severe overhead of base64 encoding (around 33% larger than original) and potential caching problems.
If you don't have any particular reason to store image data in your database then I strongly advise that you just do it the normal way.
This is because, your database engine will be taking a significant performance hit since you will be getting and putting more data than necessary.
Furthermore, BLOB fields on MySQL tables are significantly larger than other tables in terms of size and perform slower on most scenarios.
Just imagining the overhead on your server once you implement this gives me the chills. ;)
I guess it all boils down to scalability. Once your database fills up, your server become less responsive and will eventually become a real hog. Your next options would be to increase server RAM or revise your code to accommodate the bigger load.
Just my 2 cents, hope this helps!
Good luck!
Actually, the best aproach is to have a PHP script to output the binary of the image with proper headers (say getimage.php) and the script used to generate the HTML will have a code like this:
$get_pics = mysql_query("SELECT id FROM images WHERE user='$userid' ");
while($imglist = mysql_fetch_array($get_pics))
{
$new .= '<img src="getimage.php?id='.$imglist['id'].'" title="'.$imglist['caption'].'" />';
}
So the HTML will look like:
<img src="getimage.php?id=12345" title="the caption of" />
You must have a primary key (why not already?) on the table images, let's say id.
The "getimage.php" script shall extract the binary and output the content (assuming that the field img_location contains the actually content of the image:
<?php
// this will output the RAW content of an image with proper headers
$id=(int)$_GET['id'];
$get_img = #mysql_fetch_assoc(#mysql_query("SELECT img_location FROM images WHERE id='$id' "));
$image = imagecreatefromstring(base64_decode($get_img['img_location']));
if ($image){
//you may apply here any transformations on the $image resource
header("Content-Type: image/jpeg"); //OR gif, png, whatever
imagejpeg($image,null,75); //OR imagegif, imagepng, whatever, see PHP doc.
imagedestroy($image); //dump the resource from memory
}
exit();
#mysql_close();
?>
This approach will give you flexibility.
However, you may need to check and sanitize the variables and choose another method of connection to MySQL, as MYSQLi or PDO.
Another good idea is the use of prepared statements to prevent SQL injections.
Related
I know I can compare two images (to check whether they are visually the same, not to check their file format, EXIF, etc.) using compareImages( Imagick $compare , int $metric ) function of ImageMagick library in PHP (also available in several other programming languages).
Sample codes to compare 2 images in PHP:
<?php
$image1 = new imagick("image1.png");
$image2 = new imagick("image2.png");
// TODO: have to resize 2 images to same dimension first
$result = $image1->compareImages($image2, Imagick::METRIC_MEANSQUAREERROR);
$result[0]->setImageFormat("png");
header("Content-Type: image/png");
echo $result[0]; // display the result
// TODO: Add exception handling
?>
But with thousands of images to compare against, this function seems to be inefficient, as it can only compare one by one. Is there any function that I can use to make a fingerprint (something like that) of an image, so that I can easily search in the database?
Methods I can think of:
Convert the image to Base64 string
Fetch few sample pixels from each image, store the colors in the database (but this method is not accurate)
Use Image recognition library (something like Machine Learning) to add some tags for each image, then search by tag (this method is not accurate as well)
(anything else?)
All suggestions are welcomed.
p.s. programming language does not necessary to be in PHP.
You could use the getImageSignature function, which will return a string containing the SHA-256 hash of the file.
So either loop over all images and add the image signature to your database of images, or just add the signature on every comparisson you perform.
Hope that helps.
When I take content of a picture I try to dump it like that:
$filename = '(900).jpg';
$im = file_get_contents($filename);
var_dump(serialize($im));
When the picture is under 1mb everything works, but if it is more than 1mb browser crash can you tell me why is that a browser issue or some limitation of file_get_contents() function?
The only limitation of file_get_contents might be the memory which is allowed for PHP to use. And the default is about 128 MB.
It is a browser "issue" if you want to call it that. Outputting so much debug information to the browser is not a good idea as you can see. Additionally there is no benefit in viewing a binary file as text.
If you want to find out if the variable is set, you can use functions to check the size of the (binary) string e.g. mb_strlen().
A better way would be this
$filename = '(900).jpg';
$im = file_get_contents($filename);
// check if the file could be loaded
if ($im !== false) {
// start your processing
}
But this does not check what kind of file you have loaded into the string. If you must store the file into the database - which is considered very evil - you can either store the binary string into a BLOB type row or encode the binary string with base64_encode() and store it into a text type. Both of this solutions are also not recommended!
If you need to store image information into the database, you should think about using references to the files - e.g. the file path. Your primary objective is to secure that the database information and the filesystem information is always synchronized.
I'm having a problem with retrieving some blob data from sql server and processing that in php to convert it back into an image.
Here is an example of one of the blobs (varbinary) in the database:
0xFFD8FFE000104A46494600010101006000600000FFDB0043000D090A0B0A080D0B0A0B0E0E0D0F13201513121213271C1E17202E2931302E292D2C333A4A3E333646372C2D405741464C4E525352323E5A615A50604A51524FFFDB0043010E0E0E131113261515264F352D354F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4F4FFFC000110800FA00FA03012200021101031101FFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00EBAFD7E7527FBB59B28E2B56F86761F6359B30E0D7A38797BA6125A904838E6AB38E2ADC99239AAD20AED818959C540E2AC3D42D5A0C81BA5466A56A8CD4B1919A6114F3DE9A6A58C6F1EB4D3B7A53B38ED9A427DA95860ACA8C1949CA9C8356EDA75FB3F9625113F9BBD988FBC2A8E4775A3E5CD43498D3B172ED61118B98721659CAAE3B28A921B5886A7736B202C150988FA90335477B796620C761E76D4925CCD2BABBB92CBD0FA54F2BEE526598E78E0580CAADE7DB295D831B581F5ACFEA4FB9CD3B93C9A4A12B09BB8DC518A7525500868C52D266900838ED4A49C7DDC51ED461BD45030A5033DF140A08CD21A1E14776153DA0517B6DCF3E6AFF003AAC1467AD4F6808BDB6C74F357F9D4CB6348EE7A09E188A314ADF7A92BCF66E348E693069E68A41712F07CAB59B28E6B52E86631F5ACF9508AE8C33D0E39EE557E9555EAD482AB49D2BD08183DCACE3D6A063561EA06AD4085B9A88D4AC2A36A9652236A61EF4F34D348637F1C5369DC7A5348A9180507D290AAFA54B15AC931F9178F5AD186C553E6719F5CD6152B461B9A469B6648427EE8A3691D456DF951A1F97039EF51DC1557F9555B8E7B66B9FEB8AFB1AFB13242B303804D3769C55F0E40DCBF2A7438A64AB8200C1471F7B1D29FD690BD91468A9E583CBC7A7AD4722143C8E3D6B68558CF622506861F4A4C529A4AD0810D1807BD2F5A4E3D0D318BD28A323B52D21A018F43562D4FF00A5DBFF00D755FE7502B1C74A9ED4E6F6DBFEBAAFF3A996C5C773D09BAD14A7A9A2BCD7B9B8DA29475A29082E8ED873EF59AF3EDCF15A5763FD1CFB1159128E0FB574E1926B538AA2F788D9B7AE718AAEF52AFF00AB3F5A89EBD08A322BBD42D533D42D5A8D10B544D52B544D498C61A61A71A69A9631BDAB474FD364BA6590A9110FD7D6A2D32C5F50BA112F083976F415D3DD4F1DBC09142005DBB540EA6B8F115B93446F4A17DCA0C91C24AC58F73DAB3E6B83E66064FA9ABB70AC63545FE2E4D675DAEC2B10E5BD3D2BCB6DB77675DAC4734FF74EC24F40077AAF2C37329DCFF27A0F4A9D9763139E9D4FBD3D14C8B82480DF99A57B0CA2AAD0F59467BFFF005EA600CA9B46016E9E94A6D2477F2E24271DEA636C2D700B8761E9D050E43512A90EA76BF5ED9AB02D9DA262C98CF38ED4D9641B36B2641EFE95620BB678C212368FBA69A9B8EA84E3732E64F2E42B51F7AB97199D8F1F30F4EF54CF5AF52854E789C9521CAC4A39ED49CD193DAB720773DC51483777A0500870CFAD4F6A7FD32DF27FE5AAFF003AAFF854D6E7FD2EDCFF00D355FE7532D8B8EE7A29EA696985BE63466BCD6B53A5A149E6939A6E79A7669582C3AEFF00E3DDFF000FE7553C8C59C8C06E6299AB575FEA24FF0074D2DA10F6AA3B6083550938C558E5946ECC1404401FB3138A864AB0C4AC623EC8481559CD7AB4F557399AD481EA17A95EA162335B0113546C69EC6A327D6932861A631F41927A0A79AB5A3C1F6AD5EDE223E50DBDBE82B39CB953638ABB3A0B6B75D2F4600E1659802E7B8CD5447592F2495CE6281368F734DD6AE45E4F2C71B7CB11C63D71FF00D7355A43E445144DC1DBE63FD4F4AF22A36F56764158B1713ED185FBE7A0F4AADE5012967396DB9C9EC2A1B498493493CDF71326AC5AFF00A4106438327EF256FEEAF65AE67A1B2D4AF2A858BCD97E541D07AD578E59EE24D907C89DCF7A7DF5C7DB270B18C44A78156ADD04716C8C727A9A1E88D231B8C5490831A938EE7B9A916D58617A9AB914585AB10C79901238AC9C8D5452316FAD5A3F982E57B8AAF1C6228CEC3943D33D45749790064615CD5DB794D81C63AD5C5DCCE6BA906F68E40E3AA9E29972143878FEEBF3F4A567DEC31DC5315832321EC78AEAC3CF96461523CD123E293AD1D3AD1B881C015EAA38838F53467D28DCC7D28FAD0342807D6A5B7E2E60FF00AE8BFCEA206A48BFD7C3FF005D17F9D44B62E1B9E82EDF391407C1A809F9CD2E6BCE7B9E872126FC9A5CD459E69327D690F91176EBFD53FF00B86A0D3E4F9244F4008AB171F748F55359F64FB657FF00AE59FCAB5A6AF03CD968CA3236770F73559CD485B2C7DF9A85CD7A94D591CF2DC89AA16A95AA1635A08889E2A36A7B546D4994349AD5F0F15B79AEEF1FFE5942715946AED9B797A7DF64F2C8303DB35856D60CB86E1619621DCFCF2924FE26A3D4A5DF3CA7D5B68FA0A34A62F247BB9232DF90AACC7794CFF13126BCC99D682572904708EAE79AB8D2F9566C13EF487693FCEA9121A6690F45185AB1102E2353D867F1358C91AC092CED8B0040E2B6ECED323245416FB502A8EB5A11CC1547A560F53A2D65A129815476A458C29A4F3F70EB8A723231E5AA58B55B89291B4E6B94D6D76C848AE9E7EF83915CEEB684A034E1B8DAF74C781C1033D8D21936CC73DCD436E712107B1A27EBB87635D0B730E84CE307EB49BB1DA856DC9CF5A4DD8E82BD5A52BC4E29AB30DD9ED4A293713E94035A123854911FDFC5FEFAFF003A8853E33FBE8BFDF1FCEA27B33486E7745BE63466A266F98D2E6BCBE6D4F5F97424CF349BA99BA9334B98394D6B8EDF4AC8B6931337BC26B52EDB010FD6B091B13C7CF5CAFE75D9415E078D5374400FCDF8531CD2670E47A714D735E8C0E796E46E6A16EB5231A85CF35608631A8C9A79EB4C35230C66AC5B93E5DC21E8D1E07E073500CF6A9A2C88E618392A39F4E6B2A9F0B2E1B8BA4FEEE2B990F25206FC3354F70523FD95AD3853C8B1D41B8C14403F1AC763D7DEBCD99D687827CA3EBD6A682531C8A4F4AAD26E3136CEA3029DB5C8DC33D060562D5CD63A1B90CBE6B02B524B706206A0D023692ECC67A119FA55BF105A9B78C48A383C560D6A74A9AD8CC9B5094F0A702A34BF981FF5BC55668D8EDF43D6ABCD6F299F099D99AB514CCDB77365350949E5F34B76EB716FC761541207DC00EDD2B492CDD2DF2FDEB2692668B639B2BB249298C77023DAACDF26C91F1E954D9B0EA3DB15BC753092B3278FEE7E00D2E403D29909C02A7E94F3807AD7A3877EE9C7556A1BBFD9A5A6E467A9A3BD74198EA7A7FAD8FF00DF1FCE998E6957FD627FBC3F9D673D8D29FC476A4FCD4035113F31A037BD78CE5A9EEA5A1293499A66EC8A4CFBD2B8F94D6BF6C4087DCFF2AE7E5930411F515BD7EACF6CAB18258B1007E06AA8D1375B1F324C4B8E31D057A546A460ACCF0AA2BD8C12FF00383EA69CE6A1991A29DA29061D1B045399ABD0A6EE8E59218C6A3634E635113CD5B62109E69B9A526999A91A2752315247200768E49E83D4D54DC7B54D68C12E559BEF745CF407D6A25AA2A3B93DE964B4960279D819BEB9AA3044D3B6101356E67F3B53981FBB2A613E95B3E1DB248ECDA46197663D6BCBACEC7753573321D3A409964A78B07C80178AEA19507DE038A8A578829E0015CAE4CE88BF22AE836EB0C92123E622A6D5944F008DAAC5828C6F1C67A5173106527BE2A1EC24D739C97D95F7151DAACC7A7CAD8C2D5876FB3DC0571D7A1AD582E1368E94B999B495B5452B4D2C4443CA79F4AB374A8622A3153492A30EB542E1F00806B36114D9CBEA400958565C9D8E38AD3D539989AA823530B67BF4AE9A7A98D4B5C8E13B816F4EB4F3D6990A94420F7A757A9423CB1386A3BB1452D2519AD8CC70A553FBC4FF00787F3A666957EFA7FBC3F9D44FE134A7F123AF2DCD01BB5464F34A1ABC093D4FA28AD0933466A3DD499A5CC3E537E6B8F261DE98387DBF9D73BA86A5792AC9990AF94410ABC6715AF7C7FD02E71D5641FD2B33529A16B584018924EA074FC6BD4A6D276B1E04E3A261ADAABC51EA11F2B346A4FD6B318F356524927F0ACF00E5ECE4E7FDDAA6581031E95DD877A58E6A82139A8C9A5269A48ADEE662134DA09A6F7A4C63B3C629A4D1DE92A58CBF6204CD193F7A3048F7AE834563F63955BAA3FE86B99B393CAFDEFA657F3AEAB4D402DE439CEE406BCFC4C3A9D54643A69B1D4D67C92B4ADB16A4BB279C557B7521B9EA6BCE67A11D8B0754FB3CBE511B401F2D52BDD6A461B53A54D7712CCA32391D0D65496CCA4E7A5349013FDADEF634047FAB3D6A78EE191704F4AAF6A0451FD698EC779C77A9B1772F0BA39EB4493175EB544120669EAD52D0D33235490ADE6C1D319AAEA4EDE69DA83EFD41C8FA521E302BD0C2C2ECE0C4480D2504D257A28E3168A4CFAD1400B9A33F32FF00BC292933F32FD47F3ACEA7C2CD69FC48EACB734A0F15193CD1BB8AF9D93D4FA58AD1126EE69335196A326A2E558DBBCFF8F7BC5F707F9573F7C77C413BA2EE07DB35BF77D6E97D5335CDDD36DBDB7CFDD910A1AF669BF78F9EA8BDC449A14E1F549ADE53F2DE4650FD7B5542A622D0BFDE8C953F8557676B5BB8E65E1A270D57B5260FA9DC3AFDD760C3F1506BB68FC4CE49EC5763C530F5A09A6935D06680F5A4CD266933CD2B8C5CD2F5229B9A01C8C54817AC2D5AFA786D22EEF976F415D5AFEEAFA5CB05855420F73591A1491DBD94D328C344BBD8FA9EC2AF244FA9DC44DCADBC632D8EE7AD7156779599D14F4571973C48CB54F64AEFBA3702AEEA3CB0980C2B923F2AAF06715E74D599E841DD15277BB462028AA734F70576B29CD6BDC862BD2B26691C310D42772C83CD980C714F456FBCEDF853954B76A56047149B10F2462A26976F3E94D76C0A8243B948CF5A561DCA3F7EE4B1EE69D21F9AA4316C9C2FA75A8E71B64C577E19EA70D75A5C8F3475141A4AEF472875A5A4A4CD002E68EEBF5149413C8FA8ACEA7C2CD69FC48E98B73416A8F3CD2935F3527AB3E9E0B443B751BA999A4DD50D9A58E82ECE6593FDA8BFA560CF03CEF6CD1A33947C90066B667901788E7AC5CFE9556CE6961B76F29F67CE735ED2BF3687CEB57A666EA760EBE64A50A8273823A5510E5E3524E5B183F856EADD3CFACCF633BEEF36018CFF00785624D1986468FD0D77D27A9C324464FA5213499A435BDCCC5CD349A4CF18A4A96C63B34A2984851C9A8C4DF38C0E2B395448A49B37F48977C3736C07CD28014575413FB3B492A89B9D5318FEF31AE57C1B119F599663F7628FF535DC100F519AF3AB4EF2378E88E7ECE2964D17CABC18983B67D8E6ABDB36C90AC9C1ADCBC508370180E727EB58D771EE395E0D734B53AE9BBA2C3142307154668E2673902A9CB732C4486E71555EEDC9EF49459AA9A34D5214538C66A95CB2282462AA9B96231CD44CCCFD7A51CA3E74C19B71E299302222475E2A555A193CC961807591C0A109BD0596D645D2D75123E51279647B7AD67DD3ED5898F520835DA6B30C76DE19BB8F036C680FE35E7D34DE6451027900935BD26E2EE8E5A9A93070DD0D2E7D2A9838EF4F12153D6BB635FB9CCE059A4A884C0F5A90303D0D6CA69EC4D9A173CD21EDF5A2909CE3EB4AA7C2CBA7F123A3CF231484D349C5216AF989BD59F530D90FCD2D47BA937D4967516DA218DC48F31661D38E2ABDF591B1B490821CBB8C0EF8F6AD09A7BD9485850431EF20C8DC9C0F6A79850092E243E63A82CA0FAE2BDB8DD3BB3E5B9DDAC71335E6FD4DAE63408D18E07B8F5A65C4BE7307CFDE1CD5BB6D0B50954CBE510B3A93EFD6ABDED8C96056275233CE4F7AEEA6D5CC5950D37049C0A711EB504B29E8BC0AB9CD4484AE39DC2F00E4D44F31E82A3CD318F35CF29B668A23CBE7BD0AD51679A506B36C6767E0120FDB87F16E5FCB15D7D707E06B9F2B579ADD88C4D1E47D457795CD35A944379099AD5D14E1BAAFD6B9F130953246083820F635D35739AE5ABDA5C1BB89498643FBC03F84FAD66D5CDE94EDA333EEA30C322B39D00CF15A424120E0D579630727BD24EC6EF5286DE4D3D56A4F2E9CAB81498E2302D4DA2DBB5E6BB1381FBBB7F9D8FF002A82566256288664738515D4E9B60BA669E538323F2EDEA69C5133919DE30B954D0265CE1A690281EA2BCFFD2B6BC537C6E750F255BF770F18CF7AC51CE735BC11CD37A8B9E682690521AB20783C50AC45314D2D17B01616604734FCF4F4C8AA99A91642383C8AD15576B31C56A75CC90C9830C83E8D50CB0C89D47E559EB2064478DF21AA54BC9A2E0938FCEBC6A90D59F434EA7BA897752EE14A9770CA3F78801F55A5CDBFFCF43F9563CA6AA68F41750C857D6AA4D90B8CA8C8DBCF6AB16E2558B133066CF503B5569C095976329F30E00AF5E9EF63E59E858B4903C4071F2FF2AE5BC5D7704D7104513067849DC7B0CF6A6EA5AABDA1682062B21055F1DAB9991C9249249279AE88C39657B8AF715DF9EB559CF34AE735196C9C553770485CD358F14D071C50C722A6E31334A0E2980E6941A406868D75F64D62D2E3380B200DF43C57ABE73C8E95E32C4ED38EA3915EAFA1DE8BED1AD6E01C96401BEA2B0A8B5B948BF4D911648D91C02AC3041A5A2B30395D474796DD9A4B40593AECEE2B36397770C39AEE1C771D6B2352D2E1B866920C24A3AE3BD0CE884FB984101A8A62116ACBC13C1C4B190077ED4FD3EC5B50BC45C1F290EE73DB1E94AC68DD9167C39A61321BDB81F37FCB307B0F5AD0D7AF16CB4E9A627955E3DCD6778975F4D2E35B5B12A67041623A281DAB96D775F7D52DE18F694C72E33C1356A37306FA98CEED23B3B1CB31C9A41D293BD28AD92B1930CE29B4A4E29280115B0DCD3CFAD447AD3D4E45260389A33C534D266931A2EE9F77F66981750F19E194D6CEEB6B8198DF61F46AE6B357ED184B1156EAB5CD5A0B73BF0B59AF74BF2DB32F207E22A2C37F78D2473CD0FDC6C8F4352FDBFD6DC572D99E85E27A816C118049F6AE37ED522DC4E232C3CB96419279EB9C0AE81F5B813384635CADD5DE67B897CB004A59BE99AF568C923E7E507D4CBBD9CDC5DCB331E5DB35519B9A1CF7A8F76456CD99D818F35131C1A7138A63549404F7A33C5341E293348001E714BDEA3CF34ECE2802406BB1F00DFF00171A739E87CC8C7B77AE2C1E6ADE977CDA76A96F76A4E11B0C3D54F5A892BA291EB7BA862150924003A9359BA8EB9A7E9F00964983B30CAA29E4D70DAD7892F35362818C50F645FEB5928B651D26BBE2B82D51A0B02259BA17ECB5C9D9EB77D6974D3ACECCCC72E18E41ACB273DE9335A722B0B99F43B787C5F6EEA7CFB7393D40E41AA37DE277F25A0B08C5BC47D3A9FC6B96C907228672DD4E6A79115CFA0B34CF239662493D49A889ED413DA93156886EE28A507AD213487AD00293934B9A68EB4B4AE035A950F6A0F2298386A00918E2909E828278A4079A4315BB0AB5A7B62E369FE21550F269F136C915BD0D44D5D1A52972C93361979A660D4B9CF3EB498AF3EE7B3BEA5E9E49D24D8CE738078AAD3330898B13E95A779008E601B04B02E0F5E09E2B375120468A3B9E6BDA492D8F024D9418E73509E0D399B0698E7BD0D92048A6934DCD373CE2A4629348C78A46A4CE452012941E29A6941ED400EC9A5CD37346690C7BC8CD8DCC4E38E69377BD333403400FCD349CD266933E9400B9C5213484D25002F7A052668CD218A7DE9282690726801451DE8A4A005A69EB4A4D35A900ECF145276A33C5200079A78EA6A35E94E5EB81C9A18D1B16927996CA4F51C54D556C5764441EA4E7156ABCFAB1B48F6684AF046BDEE56FE75CE406E39CE38CD63EA4FF00BD51E82B5AFE42DA95D0EC8C10718EDD7F5ACEBD11B85CE370EB5EA2678D35A996C78A613DAAD340AC3E538AAD242CA7D69DC8223C1E69A4F7A71F7EB4C348001C8E6901EDDE9338349FC5400ECD341F9A90D2FD295C63FB52669074A4273400A0F3467D29A0D2E68016933484D264D003A8A4A2800CF140A28A4004D03AD21A5A062D266933484D20173CD21EB477A0FB53003D29B93C0A5278A1137375C0F5A402806A7876A7CCDD69B26D00246327B9A5588F1938A4C116AD6567B8C8E17157B9ACD122C2B84FBD8EB57926528A491C8AE5AB0BBB9E861AA5A3666DEA5118B5099C0F965C375CE1BB8AC3BE4733BB0E8715B37FFF001F03FDDAA173F78FE15DE91C13DCCB32489DCD219D9860E2A69FEED556E94729023B67A8E69B8C8E3A52B75A58BA5160217E29A1B9AB173F74D551D68E50B8FCD00D3475A5FF001A2C2B8B9A4CD21EB41EB4728EE3BE9453569F4AC171A4D20E94E341E94EC2B894B4DEF4EF4A560B871EB471486834728EE1C519068ED42F4A5CA17038A4E29DDA994582E282297228EC686E94728EE31BDBAD3F6155FAD347DEA79A2C171C8CA9F5A469CB74E951B50B4B9463D4E7AD2F9AC063D284E82987A9A8944D29B3FFD9
If i copy and paste that out of the database and do the following:
Pack it into binary:
$data = pack("H*", substr($data, 2);
Then encode it with base64:
base64_encode($data);
Then I can print that out and I get the full base64 data, which I can then convert into the image:
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
All well and good.
Now if I try and do this with a script... So first I select the data from the db:
$s = odbc_prepare($ebs, "select TOP 1
binary_object as img
from BLOBS
where owner_ref = 271040");
$q = odbc_execute($s);
$record = odbc_fetch_object($s);
Then I encode that data into base64, then it looks as if it's worked, but I actually only get about 2/3 of the data:
echo ( base64_encode($record->img) );
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
To answer a question I can forsee. I cannot pack the data that comes straight out of the database like that, because when I echo it out its a load of gibberish that starts with:
ÿØÿàJFIF``ÿÛC ' .)10.)-,3:J>36F7
Does anyone have any idea where I might be going wrong?
Cheers.
EDIT Just to clarify as well, I think whatever is wrong is how I am selecting the data, because if I simply set the file header to image/jpeg and echo out $record->img without changing anything, I get about two thirds of the image, then the bottom bit is cut off.
Cheers.
Managed to get this working now. The problem was in the php.ini settings for odbc.
By default odbc has a byte limit of 4096 for data returned, so it was cutting it off at that point.
By changing this in php.ini
odbc.defaultlrl = 60000
I am now able to get all the data back and construct the image fully.
I searched a bit and came across an interesting bit of information here:
Base64-encoded data takes about 33% more space than the original data.
It sounds like the encoded string does not have enough memory. I can only guess, why that would be, but maybe the echo-command (or something else) only reserves enough space for $record->img?
Maybe you can try to store the encoded string in a variable with more space before echo-ing it?
I hope this helps at...
We had the exact same issue on our WAMP server. We switched from an oracle database to a MsSql database. The old oracle server was set up years ago so we are not sure of the settings (none of us had access to it) and the php code for oracle addressed the size in the code. There was nothing comparable in php for mssql that would do this, and even when we tried to force the size in the header it did nothing. Finally found this and some other articles and by changing 4 different php.ini files in our servers we were able to show the entire image by increasing the file size to 60000 We had to update php.ini php.ini-development php.ini-production and phpforApache on the odbc.defaultlrl line and increase them from the 4096 to 60000.
I have a built a script around class.upload from http://www.verot.net/php_class_upload.htm
Basically what it is that all my images are stored on the server in a directory called /images/
The script I built basically takes some parameters from my website such as /xyzDir/tomnjerry.jpg?w=100&h=100&fill=1&color=fff
Then I have mod_rewrite which reads the file from /xyzDir/ into a php script which then translates the width and height and returns the image.
Lately I have noticed some idiots from Turkey trying to input weird characters into the parameters w= and h=
On my script I do check to make sure only integer is allowed in width and heigh and fill can be either 1 or 2 and color can only be certain values which i check via array.
I just want to see if there is anything else I should be doing in order to avoid getting hacked.
Thanks
Always remember, Filter In, Escape Out for all user supplied (or untrusted) input.
When reading user supplied data, filter it to known values. DO NOT BLACKLIST! Always always always always whitelist what you are expecting to get. If you're expecting a hex number, validate it with a regex like: ^[a-f0-9]+$. Figure out what you expect, and filter towards that. Do none of your filenames have anything but alpha, numeric and .? Then filter to ^[a-z0-9.]+$. But don't start thinking blacklisting against things. It won't work.
When using user-data, escape it properly for the use at hand. If it's going in a database, either bind it as a parameterized query, or escape it with the database's escape function. If you're calling a shell command, escape it with escapeshellarg(). If you're using it in a regex pattern, escape it with preg_quote(). There are more than that, but you get the idea.
When outputting user data, escape it properly for the format you're outputting it as. If you're outputting it to HTML or XML, use htmlspecialchars(). If you're outputting to raw headers for some reason, escape any linebreaks (str_replace(array("\r", "\n"), array('\r', '\n'), $string)). Etc, etc, etc.
But always filter using a white-list, and always escape using the correct method for the context. Otherwise there's a significant chance you'll miss something...
create a validation class to validate your post params like so.
class MyValidation
{
public function is_interger($val)
{
return is_int($val);
}
public function within_range($val,$min,$max)
{
if($this->is_interger($val))
{
return ($val < $max && $val > $min);
}
return false;
}
public function is_hex($val)
{
return preg_match("/^([a-f0-9]{3}){1,2}$/",$val);
}
}
And use to validate your values.
Example:
$Validator = new MyValidation();
if($Validator->is_hex($_POST['color']))
{
//Sweet.
}
Make sure the image name does not contain string like "../". Depending on your script, that could be a way to step out images directory and make the script deliver other files.
You should use intval() for ensuring that the width and height are integers
$width = intval($_GET['w']);
$height = intval($_GET['h']);
You can do
$fill = $fill == 1 ? 1 : 2;
Which is a ternary operator, so if it's anything apart from 1 it's going to be set to 2.
As for validation of hex, the rules of hex dictate that it must be in range of 0-9/A-F.
$color = preg_replace('/[^0-9a-f]/i', "", $_GET['color']);
Hope that helps.
(It should be noted that my suggested code will perform the manipulation required to make it suitable for your page, rather than confirming that is is valid before hand)
No one's mentioned the filter extension here which provides great filtering natively implemented in the PHP engine. IMHO this is a great extension and should always be used before rolling your own filtering code. For example, checking for an integer is as simple as:
<?php
if (filter_var($value, FILTER_VALIDATE_INT)) {
//Valid Integer.
}
?>
Validating a hex number can be done with:
<?php
if (filter_var($value, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX)) {
//Valid Hex number
}
?>
Then I have mod_rewrite which reads the file from /xyzDir/ into a php script which then translates the width and height and returns the image.
If you include the file, image or other type, it will execute any PHP code buried within it. So if you didn't shake off any possible code appended to a user uploaded image by reformatting it through imagemagick or gd into a completely new file, that is one way your server can be compromised.
So for example if you serve the user uploaded image like this...
<?php
header('Content-type: image/jpeg');
header('Content-Disposition: attachment; filename="tomnjerry.jpg"');
include('xyzDir/tomnjerry.jpg');
?>
...and if the user opened the jpg in a raw text editor and appended <?php phpinfo(); ?> to the very end before uploading it to your server, then they can browse to and download it and extract all phpinfo details of your PHP installation from it.
But since you mentioned resizing the image first, you're probably not even serving the image this way. So you should be safe from this attack.
How can i restore or access MySQL blob field so I can preview it as HTML using PHP codes? Is there an available function in PHP so I can store as jpeg those blob field.
Storing is easy. Assuming you have a mysql table with BLOB field for pictures....
Once the image is uploaded you get the contents of the file into memory and then insert into the blob field.
<?php
$file = '/tmp/MyImg.jpg';
// you migh want to escape it just in case
$data = file_get_contents($file);
// Insert into database
$sql = "INSERT INTO my_picture_table (`picture_blob_field`) VALUES ('$data');"
?>
Retrieving is fairly simple as well. It is simpler to make a separate file to load images from blob.
<?php
// file = getPicture.php
$id = (int) $_GET['id'];
$sql = "SELECT `picture_blob_field` FROM `my_picture_table` WHERE `id` = $id"
// query the db
// store data into var $picData
// Set the content type and print the data.
header("Content-type: img/jpeg");
echo $picData;
?>
This is all you have to do... Now in HTML page just create an
<img scr="getPicture.php?id=PICTURE_ID alt="blah blah" />
Note that above example is for JPEG type, store the file type in the db and then use it to specify file type with header("Content-type: img/xxx")
Hope this solved your problem.
I found an example/tutorial on storing images in mysql. If above is not clear look through the code (its paginated, so look at the other pages)
The code presented above is vulnerable to SQL injection attacks and will in any case fail at the first byte of the JPEG that happens to match the ASCII code for a quote mark (which should happen quite quickly). I do see your comment that you "might" want to escape the data, but it should be emphasized that in a big binary file, there will almost certainly be a byte that matches the quote mark. It's not "just in case," it's practically every case.
Use mysql_real_escape_string() on the JPEG data and the id parameter (which comes from the user, who may be malicious). Better yet, use PDO and parameter substitution to avoid that mess.
Also, the content type must be image/jpeg, not img/jpeg.