Is it possible to work with following kind of image urls?
http://product-images.barneys.com/is/image/Barneys/503230930_product_1
Currently I'm using following code to determine remote image formats. But I don't know how to handle the above mentioned example. Thats one example. Normally they do it for dynamic image resizing.
if($source['extension'] == 'png') {
$type = 'image/png';
}
<?php
$f = tempnam("./", "TMP0");
file_put_contents($f,file_get_contents("http://product-images.barneys.com/is/image/Barneys/503230930_product_1"));
if(getimagesize($f)){
$type = 'image/png';
}
$f file has now the image do whatever you want or delete it using unlink($f);
You could make use of finfo::file extension. You don't need to use cURL for this context.
<?php
$remoteImgTempName = 'someimg';
file_put_contents($remoteImgTempName,file_get_contents('http://product-images.barneys.com/is/image/Barneys/503230930_product_1'));
echo finfo_file(finfo_open(FILEINFO_MIME_TYPE), $remoteImgTempName);
OUTPUT :
image/jpeg
Related
I'm facing an issue with file uploads using Yii2 framework, but I think that question goes deeper than a framework problem. I have an app that allow the user do pdf files uploads, until here my app works fine but I'm in trouble when some smartass rename the filename extension from anything to pdf. The app isn't validating this kind of trick.
I tried without success to validate the mimetype. Now I'm looking for another way.
Anyone know how to block this kind of cheat?
Its better to keep it simple and just use this
<?php
$finfo = finfo_open(FILEINFO_MIME_TYPE);
if(finfo_file($finfo,$filename) == 'application/pdf'){
// input file is pdf
}
?>
Since you said its not working for you you can try these
if you are using a Linux server you can use the shell commands to check them mime type
<?php
function detectMimeType($filename='')
{
$filename = escapeshellcmd($filename);
$command = "file -b --mime-type -m /usr/share/misc/magic {$filename}";
$mimeType = shell_exec($command);
return trim($mimeType);
}
?>
Or you can try this method .Here we assume that Pdf file starts with a %PDF string .[usually it does start with %PDF].
<?php
function detectFileType($filename='')
{
$handle = fopen($filename, "rb");
$contents = fread($handle, 4);
fclose($handle);
if($contents == "%PDF")
{
return "application/pdf";
}
else
{
return "application/octet-stream"; //unknown type
}
}
?>
[this code is not tested ]
Refer these links you will get some more info about what went wrong
http://php.net/manual/en/function.mime-content-type.php
http://php.net/manual/en/ref.fileinfo.php
the best way is to check mime type of file :
http://php.net/manual/en/function.finfo-file.php
<?php
$finfo = finfo_open(FILEINFO_MIME_TYPE);
if(finfo_file($finfo,$filename) == 'application/pdf'){
// input file is pdf
}
finfo_close($finfo);
?>
The problem was solved using the mime_content_type function.
Check the function here php.net
This function returns the real mime type.
I want to rotate an uploaded and retrieved image from one location. Yes i am almost done. But the problem is, due to header("content-type: image/jpeg") the page redirected to another/or image format. I want to display it in same page as original image in. Here my code..
$imgnames="upload/".$_SESSION["img"];
header("content-type: image/jpeg");
$source=imagecreatefromjpeg($imgnames);
$rotate=imagerotate($source,$degree,0);
imagejpeg($rotate);
i also did with css property.
echo "<img src='$imgnames' style='image-orientation:".$degree."deg;' />";
But anyway my task is to done only with php. Please guide me, or give any reference you have
thanks advance.
<?php
// Okay, so in your upload page
$imgName = "upload/".$_SESSION["img"];
$source=imagecreatefromjpeg($imgName);
$rotate=imagerotate($source, $degree,0);
// you generate a PHP uniqid,
$uniqid = uniqid();
// and use it to store the image
$rotImage = "upload/".$uniqid.".jpg";
// using imagejpeg to save to a file;
imagejpeg($rotate, $rotImage, $quality = 75);
// then just output a html containing ` <img src="UniqueId.000.jpg" />`
// and another img tag with the other file.
print <<<IMAGES
<img src="$imgName" />
<img src="$rotName" />
IMAGES;
// The browser will do the rest.
?>
UPDATE
Actually, while uniqid() usually works, we want to use uniqid() to create a file. That's a specialized usage for which there exists a better function, tempnam().
Yet, tempnam() does not allow a custom extension to be specified, and many browsers would balk at downloading a JPEG file called "foo" instead of "foo.jpg".
To be more sure that there will not be two identical unique names we can use
$uniqid = uniqid('', true);
adding the "true" parameter to have a longer name with more entropy.
Otherwise we need a more flexible function that will check if a unique name already exists and, if so, generate another: instead of
$uniqid = uniqid();
$rotImage = "upload/".$uniqid.".jpg";
we use
$rotImage = uniqueFile("upload/*.jpg");
where uniqueFile() is
function uniqueFile($template, $more = false) {
for ($retries = 0; $retries < 3; $retries++) {
$testfile = preg_replace_callback(
'#\\*#', // replace asterisks
function() use($more) {
return uniqid('', $more); // with unique strings
},
$template // throughout the template
);
if (file_exists($testfile)) {
continue;
}
// We don't want to return a filename if it has few chances of being usable
if (!is_writeable($dir = dirname($testfile))) {
trigger_error("Cannot create unique files in {$dir}", E_USER_ERROR);
}
return $testfile;
}
// If it doesn't work after three retries, something is seriously broken.
trigger_error("Cannot create unique file {$template}", E_USER_ERROR);
}
You need to generate the image separately - something like <img src="path/to/image.php?id=123">. Trying to use it as a variable like that isn't going to work.
I want a PHP to be able to send 1 of 3 images, depending on a $_GET[] parameter. I have the images as three separate PNGs right now, and would like the PHP script to have those embedded in it, then return the specified image. So, I want one PHP script instead of 3 images. Is this possible? I don't need to create special images on the fly, just print out one of those. Thanks!
If your images are in files, use PHP's readfile() function, and send a content-type header before outputting it:
<?php
$imagePaths = array(
'1' => 'file1.png',
'2' => 'file2.png',
'3' => 'file3.png',
);
$type = $_GET['img'];
if ( isset($imagePaths[$type]) ) {
$imagePath = $imagePaths[$type];
header('Content-Type: image/png');
readfile($imagePath);
} else {
header('HTTP/1.1 404 File Not Found');
echo 'File not found.';
}
?>
EDIT:
You could also embed your images in the script by encoding them e.g. as Base64, then embed them as strings in PHP, then decode it there with base64_decode to deliver them:
<?php
$imageData = array(
'1' => '...', // Base64-encoded data as string
...
);
$type = $_GET['img'];
if ( isset($imageData[$type]) ) {
header('Content-Type: image/png');
echo base64_decode($imageData[$type]);
} else {
header('HTTP/1.1 404 File Not Found');
echo 'File not found.';
}
?>
You could also use PHP to encode the image on the command line. Just execute this PHP script in the command line (php script.php image1.png image2.png image3.png > output.php) and save its output, and incorporate it into your script:
<?php
$imageData = array();
foreach ($argv as $index => $imagePath)
$imageData[(string)($index + 1)] = base64_encode(file_get_contents($imagePath));
echo '$imageData = '.var_export($imageData, true).';';
?>
I have not tested the following, but it should work. Use this script to get PHP code that will contain the image data.
To get the image:
$image = base64_encode(file_get_contents("image.png"));
// The string $image now contains your image data.
Get this (potentially big) string in your code where you want the image, for each image. Print it and copy it then paste it. Import it as a text file over the web. That's up to you.
Then, to print the image (only the image as if the PHP script were the image), do:
header("content-type: image/png");
print base64_decode($image);
Of course, you would put each image data in an array or something like that.
Let me know if it works.
Yes, it's possible.
Do this:
Write a php script deciding which image to output.
Set the appropriate headers with header() function (I.e. Content-type)
Open the file, read it and send it to the output stream.
Remember that you will probably lose any benefits from browser's cache with this approach...
A fast but not really secure nor elegant way to do it...
<?php
switch($_GET['type']){
case "1":
$image = "image1.png";
break;
case "2":
$image = "image2.png";
break;
case "3":
$image = "image3.png";
break;
}
header('Content-Type: image/png');
readfile($image);
?>
the moral of the story: use header() and readfile() =D
I need to check whether a given image is a JPEG.
if ($_FILES["fname"]["error"] > 0) {
$imgData = "hyperlink/holder.jpg";
} else {
$imgData ="hyperlink/" . $_FILES["fname"]["name"];
}
// Only accept jpg images
// pjpeg is for Internet Explorer should be jpeg
if (!($_FILES["fname"]["type"] == "image/pjpeg") ) {
print "I only accept jpg files!";
exit(0);
}
When it goes to first statement in the first if statement it always gives I only accept jpg files!
How can I fix it?
Try the exif_imagetype image function.
Example:
if(exif_imagetype($filepath) != IMAGETYPE_JPEG){
echo 'Not a JPEG image';
}
PHP has such good image-type support, i wonder why you are restricting your app. In just a couple lines of code you can deal with any input format and convert to jpeg, if that is a requirement...
$im = imagecreatefrompng(input_filename)
imagejpeg($im, output_filename);
I believe the following works:
Also note that:
(exif_imagetype($ImagePathAndName) == IMAGETYPE_JPEG)
only reads the first few bytes looking for an image header so isn't really good enough to confirm if an image is corrupt.
Below I have it in a logical “and” statement i.e. both of these tests must be passed in order for the image to qualify as being valid and non-corrupt etc:
if ((exif_imagetype($ImagePathAndName) == IMAGETYPE_JPEG) && (imagecreatefromjpeg( $ImagePathAndName ) !== false ))
{
echo 'The picture is a valid jpg<br>';
}
Note: You need to place this line of code at the top of the php code in order to avoid seeing the warning messages from imagecreatefromjpeg( $ImagePathAndName ) when it encounters a fake/corrupt image file.
ini_set(‘gd.jpeg_ignore_warning’, 1);
Why don't you try creating an array of exceptions (the files you want the user to be able to upload).
// Hyperlink for your website
$hyperlink = "http://www.yourwebsitehere.com";
if($_FILES['fname']['error'] > 0)
{
$image= $hyperlink . "/holder.jpg";
}
else
{
$image = $hyperlink . "/" . $_FILES['fname']['name'];
}
// Only accept files of jpeg format
$exceptions = array("image/jpg", "image/jpeg", "image/pjpeg");
foreach($exceptions as $value)
{
if($_FILES['fname']['type'] != $value)
{
echo "I only accept jpeg images!";
break; // Or exit();
}
}
When using $_FILES, you are relying on informations sent by the client, which is not the best thing to do (you've seen it's not always the same, and, if I remember correctly, $_FILES['...']['type'] can be faked).
If you are using PHP >= 5.3 (or can install PECL packages), maybe you can give a look to the extension Fileinfo. If you are using an older version, what about mime_content_type?
And, as said by Scott, why allow only jpeg?
Looking about the code better : when you are in the first case (error > 0), you are assigning a default file to $imgData? Why the spaces around "hyperlink"?
And why do you always use to check the content-type, even if there was an error a couple of lines before?
To finish, did you have a look at the manual (Handling file uploads)?
Check the mime (Multipurpose Internet Mail Extensions) type of file with this code. And verify your desired type. You can also detect png,gif with this code.
if($_FILES["fname"]["type"] == "image/jpeg")
{
echo "File type is JPEG";
}
I am looking for a way to take a user uploaded image that is currently put in a temporary location ex: /tmp/jkhjkh78 and create a php image from it, autodetecting the format.
Is there a more clever way to do this than a bunch of try/catching with imagefromjpeg, imagefrompng, etc?
This is one of the functions of getimagesize. They probably should have called it "getimageinfo", but that's PHP for you.
//Image Processing
$cover = $_FILES['cover']['name'];
$cover_tmp_name = $_FILES['cover']['tmp_name'];
$cover_img_path = '/images/';
$type = exif_imagetype($cover_tmp_name);
if ($type == (IMAGETYPE_PNG || IMAGETYPE_JPEG || IMAGETYPE_GIF || IMAGETYPE_BMP)) {
$cover_pre_name = md5($cover); //Just to make a image name random and cool :D
/**
* #description : possible exif_imagetype() return values in $type
* 1 - gif image
* 2 - jpg image
* 3 - png image
* 6 - bmp image
*/
switch ($type) { #There are more type you can choose. Take a look in php manual -> http://www.php.net/manual/en/function.exif-imagetype.php
case '1' :
$cover_format = 'gif';
break;
case '2' :
$cover_format = 'jpg';
break;
case '3' :
$cover_format = 'png';
break;
case '6' :
$cover_format = 'bmp';
break;
default :
die('There is an error processing the image -> please try again with a new image');
break;
}
$cover_name = $cover_pre_name . '.' . $cover_format;
//Checks whether the uploaded file exist or not
if (file_exists($cover_img_path . $cover_name)) {
$extra = 1;
while (file_exists($cover_img_path . $cover_name)) {
$cover_name = md5($cover) . $extra . '.' . $cover_format;
$extra++;
}
}
//Image Processing Ends
this will make image name look cool and unique
Use exif_imagetype() if it's available ..:
http://www.php.net/manual/en/function.exif-imagetype.php
I'm pretty sure exif functions are available by default (i.e. you have to specifically exclude them rather than specifically include them) when you install php
You could try finfo_file(), apparently an improved version of mime_content_type().
Edit: OK, getimagesize() is better..
You can call a system command (if you're under linux/unix), file if you like:
kender#eira:~$ file a
a: JPEG image data, EXIF standard 2.2
This will help you to know the Extension as well as result based on condition
$image_file = 'http://foo.com/images.gif';
$extension = substr($image_file, -4); if($extension == ".jpg"){ echo 'Its a JPG Image.'; } else { echo 'Its not a JPG Image.'; }
People are recommending using getimagesize() but the documentation reads:
Caution This function expects filename to be a valid image file. If a
non-image file is supplied, it may be incorrectly detected as an image
and the function will return successfully, but the array may contain
nonsensical values.
Do not use getimagesize() to check that a given file is a valid image.
Use a purpose-built solution such as the Fileinfo extension instead.
The relevant function in the Fileinfo extension is finfo_file():
string finfo_file ( resource $finfo , string $file_name = NULL
[, int $options = FILEINFO_NONE [, resource $context = NULL ]] )
Returns a textual description of the contents of the file_name
argument, or FALSE if an error occurred.
Example return values given are: text/html, image/gif, application/vnd.ms-excel
However, comments on the official documentation page warn that this shouldn't be relied on for validation either.