Intervention Image - how to upload images with MIME type: application/octet-stream
Asked Answered
A

6

20

Im using Laravel framework with Intervention Image library to upload and process images on my page. Everything works fine until I try to update .jpg images taken from mobile devices or from cameras. These images have MIME type application/octet-stream instead of image/jpeg. When I try to upload image with this command:

Image::make($thumb)->resize($this->twidth, $this->theight)->save($this->destination."/".$filename);

I get error:

Unable to read image from file

One uncomfortable solution is open that images in MS Paint and resave them, which will change MIME type to 'image/jpeg' and make it possible to upload it. But I would like to evade this solution at all cost.

EDIT:

I was trying to fix it by this command:

$img = imagecreatefromstring($thumb);

but it returns error: imagecreatefromstring(): Empty string or invalid image

Is there a way how to handle this type of images?

Autotype answered 18/12, 2014 at 9:11 Comment(7)
Did you search SO before asking?Loftis
Yes i did, but didnt found this answerAutotype
by the way, it doesn't work for meAutotype
I am having the same issue with uploads from Android. I am getting imagecreatefromstring(): gd warning: one parameter to a memory allocation multiplication is negative or zero, failing operation gracefully when I try to use imagecreatefromstring(//UPLOAD FILE CONTENTS//)Flamen
What is there in the $thumb, a simple string with $path or FileUpload object?Hammerless
Are you using the GD or Imagick driver for Intervention?Parakeet
Does this answer your question? PHP create image from application/octet streamRoche
T
2

Check upload_max_filesize in php.ini. It was reason in my case.

Thready answered 1/9, 2020 at 14:19 Comment(1)
Thanks, I also faced this problem and resolved by increasing the upload max filesize.Bobseine
G
1

Well, In such a case you can remove Laravel validation rule mimes, and instead, you can validate the image by its extension using PHP.

Your validation rule will look like this.

$request->validate([
    'image' => 'required',
]);

Validating image using file extension will look like this

if (! in_array($request->file('image')->clientExtension(), ['jpg', 'jpeg', 'png'])) {
   // not a valid image
}
Ganglion answered 20/11, 2020 at 17:29 Comment(0)
T
0

You may give this a try and convert it to Laravel

//The file post to the server
$image = $_FILES['imgfile'];

//array for type if octet
$MimeType = array(
    'useNew' => false,
    'type' => '' 
);

if($image['type'] == "application/octet-stream"){
    $imageMimeSize = getimagesize($img['tmp_name']); // get temporary file REAL info
    $MimeType['type'] = $imageMimeSize['mime']; //set in our array the correct mime
    $MimeType['useNew'] = true; //set to true for next if
}

//now check if we will use the MimeType or the one sent by browser
//$mimeCheck is the things you want to check. In my case i just wanted PNG or JPG
if($MimeType['useNew'] == true){ //if true, use MimeType to check file/image file
    $mimeCheckType = ($MimeType['type'] != "image/png" && $MimeType['type'] != "image/jpeg" && $MimeType['type'] != "image/jpg") && $MimeType['type'] != "image/gif");
}else{ //if not using real mime, go with the one device sent to us or browser sent us
    $mimeCheckType = ($img['type'] != "image/png" && $img['type'] != "image/jpeg" && $img['type'] != "image/jpg");
}

//returns error if image not png/jpg/jpeg/gif
if($mimeCheck){
    //return some error
}

for more doc. on this visit this link: Source document

if you like to go extreme you can try to format this to Laravel

<?php
// Retrieve JPEG width and height without downloading/reading entire image.
function getjpegsize($img_loc) {
    $handle = fopen($img_loc, "rb") or die("Invalid file stream.");
    $new_block = NULL;
    if(!feof($handle)) {
        $new_block = fread($handle, 32);
        $i = 0;
        if($new_block[$i]=="\xFF" && $new_block[$i+1]=="\xD8" && $new_block[$i+2]=="\xFF" && $new_block[$i+3]=="\xE0") {
            $i += 4;
            if($new_block[$i+2]=="\x4A" && $new_block[$i+3]=="\x46" && $new_block[$i+4]=="\x49" && $new_block[$i+5]=="\x46" && $new_block[$i+6]=="\x00") {
                // Read block size and skip ahead to begin cycling through blocks in search of SOF marker
                $block_size = unpack("H*", $new_block[$i] . $new_block[$i+1]);
                $block_size = hexdec($block_size[1]);
                while(!feof($handle)) {
                    $i += $block_size;
                    $new_block .= fread($handle, $block_size);
                    if($new_block[$i]=="\xFF") {
                        // New block detected, check for SOF marker
                        $sof_marker = array("\xC0", "\xC1", "\xC2", "\xC3", "\xC5", "\xC6", "\xC7", "\xC8", "\xC9", "\xCA", "\xCB", "\xCD", "\xCE", "\xCF");
                        if(in_array($new_block[$i+1], $sof_marker)) {
                            // SOF marker detected. Width and height information is contained in bytes 4-7 after this byte.
                            $size_data = $new_block[$i+2] . $new_block[$i+3] . $new_block[$i+4] . $new_block[$i+5] . $new_block[$i+6] . $new_block[$i+7] . $new_block[$i+8];
                            $unpacked = unpack("H*", $size_data);
                            $unpacked = $unpacked[1];
                            $height = hexdec($unpacked[6] . $unpacked[7] . $unpacked[8] . $unpacked[9]);
                            $width = hexdec($unpacked[10] . $unpacked[11] . $unpacked[12] . $unpacked[13]);
                            return array($width, $height);
                        } else {
                            // Skip block marker and read block size
                            $i += 2;
                            $block_size = unpack("H*", $new_block[$i] . $new_block[$i+1]);
                            $block_size = hexdec($block_size[1]);
                        }
                    } else {
                        return FALSE;
                    }
                }
            }
        }
    }
    return FALSE;
}
?>

to convert image to JPEG try this:

<?php
// Access the $_FILES global variable for this specific file being uploaded
// and create local PHP variables from the $_FILES array of information
$fileName = $_FILES["uploaded_file"]["name"]; // The file name
$fileTmpLoc = $_FILES["uploaded_file"]["tmp_name"]; // File in the PHP tmp folder
$fileType = $_FILES["uploaded_file"]["type"]; // The type of file it is
$fileSize = $_FILES["uploaded_file"]["size"]; // File size in bytes
$fileErrorMsg = $_FILES["uploaded_file"]["error"]; // 0 for false... and 1 for true
$fileName = preg_replace('#[^a-z.0-9]#i', '', $fileName); // filter the $filename
$newExt = explode(".", $fileName); // Split file name into an array using the dot
$fileExt = end($newExt); // Now target the last array element to get the file extension

// START PHP Image Upload Error Handling --------------------------------
if (!$fileTmpLoc) { // if file not chosen
    echo "ERROR: Please browse for a file before clicking the upload button.";
    exit();
} else if($fileSize > 5242880) { // if file size is larger than 5 Megabytes
    echo "ERROR: Your file was larger than 5 Megabytes in size.";
    unlink($fileTmpLoc); // Remove the uploaded file from the PHP temp folder
    exit();
} else if ($fileErrorMsg == 1) { // if file upload error key is equal to 1
    echo "ERROR: An error occured while processing the file. Try again.";
    exit();
}
// END PHP Image Upload Error Handling ----------------------------------
// Place it into your "uploads" folder mow using the move_uploaded_file() function
$moveResult = move_uploaded_file($fileTmpLoc, "uploads/$fileName");
// Check to make sure the move result is true before continuing
if ($moveResult != true) {
    echo "ERROR: File not uploaded. Try again.";
    exit();
}
// ---------- Start Universal Image Resizing Function --------
$target_file = "uploads/$fileName";
$resized_file = "uploads/resized_$fileName";
$wmax = 500;
$hmax = 500;
ak_img_resize($target_file, $resized_file, $wmax, $hmax, $fileExt);
// ----------- End Universal Image Resizing Function ----------
// ---------- Start Convert to JPG Function --------
if (strtolower($fileExt) != "jpg") {
    $target_file = "uploads/resized_$fileName";
    $new_jpg = "uploads/resized_".$newExt[0].".jpg";
    ak_img_convert_to_jpg($target_file, $new_jpg, $fileExt);
}
// ----------- End Convert to JPG Function -----------

echo "The file named <strong>$fileName</strong> uploaded successfuly.<br /><br />";
echo "It is <strong>$fileSize</strong> bytes in size.<br /><br />";
echo "It is an <strong>$fileType</strong> type of file.<br /><br />";
echo "The file extension is <strong>$fileExt</strong><br /><br />";
echo "The Error Message output for this upload is: $fileErrorMsg";
?>

for clearer documentation of the above code

HTML

    <div id="profilephoto" class="profilephoto" data-coupling="#content2"><img src="<?php echo $avatar ?>"></div>
    <div id="content2" style="display: none;" class="uploadbutton" data-coupling="#content2">
        <form id="imguploadin" method="POST" action="image_upload_script.php">
            <label class="cabinet"> <i class="icon-upload-alt"></i> Choose Photo
                <input type="file" name="uploaded_file" class="file" onchange="handleFiles(this.files)"/>
            </label>
        </form>
    </div>

jQuery/JavaScript

function handleFiles(files) {
    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        var imageType = /image.*/;

        if (!file.type.match(imageType)) {
            continue;
        }

        var img = document.createElement("img");
        img.classList.add("newphoto");
        img.file = file;
        profilephoto.appendChild(img);

        var reader = new FileReader();
        reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
        reader.readAsDataURL(file);
        var eventt = jQuery.Event("submit");

        $("#imguploadin").trigger(eventt);
    }
}

PHP (image_upload_script.php)

<?php
session_start();
// Access the $_FILES global variable for this specific file being uploaded
// and create local PHP variables from the $_FILES array of information
$username = $_SESSION["username"];
$fileName = $_FILES["uploaded_file"]["name"]; // The file name
$fileTmpLoc = $_FILES["uploaded_file"]["tmp_name"]; // File in the PHP tmp folder
$fileType = $_FILES["uploaded_file"]["type"]; // The type of file it is
$fileSize = $_FILES["uploaded_file"]["size"]; // File size in bytes
$fileErrorMsg = $_FILES["uploaded_file"]["error"]; // 0 for false... and 1 for true
$kaboom = explode(".", $fileName); // Split file name into an array using the dot
$fileExt = end($kaboom); // Now target the last array element to get the file extension
// START PHP Image Upload Error Handling --------------------------------------------------
if (!$fileTmpLoc) { // if file not chosen
    echo "ERROR: Please browse for a file before clicking the upload button.";
    exit();
} else if ($fileSize > 1242880) { // if file size is larger than 5 Megabytes
    echo "ERROR: Your file was larger than 5 Megabytes in size.";
    unlink($fileTmpLoc); // Remove the uploaded file from the PHP temp folder
    exit();
} else if (!preg_match("/.(gif|jpg|png)$/i", $fileName)) {
    // This condition is only if you wish to allow uploading of specific file types
    echo "ERROR: Your image was not .gif, .jpg, or .png.";
    unlink($fileTmpLoc); // Remove the uploaded file from the PHP temp folder
    exit();
} else if ($fileErrorMsg == 1) { // if file upload error key is equal to 1
    echo "ERROR: An error occured while processing the file. Try again.";
    exit();
}
// END PHP Image Upload Error Handling ----------------------------------------------------
// Place it into your "uploads" folder mow using the move_uploaded_file() function
$moveResult = move_uploaded_file($fileTmpLoc, "images/users/$username.$fileExt");
// Check to make sure the move result is true before continuing
if (!$moveResult) {
    echo "ERROR: File not uploaded. Try again.";
    unlink($fileTmpLoc); // Remove the uploaded file from the PHP temp folder
    exit();
}
// ---------- Include Adams Universal Image Resizing Function --------
include_once("ak_php_img_lib_1.0.php");
$target_file = "images/users/$username.$fileExt";
$resized_file = "images/users/resized_$username.$fileExt";
$wmax = 200;
$hmax = 150;
ak_img_resize($target_file, $resized_file, $wmax, $hmax, $fileExt);
$thumbnail = "images/users/thumb_$username.$fileExt";
$wthumb = 150;
$hthumb = 150;
ak_img_thumb($target_file, $thumbnail, $wthumb, $hthumb, $fileExt);
// ----------- Write Image File path to the server ---------------------------------
$sql_user = "myuser";
$sql_pass = "mypassword";
$sql_ip = "localhost";
$sql_DB = "mydb";
if ($moveResult != true)
    echo("couldnt write file path to database due to unsuccesfull upload");
    else {
    $mysqli = new mysqli($sql_ip, $sql_user, $sql_pass, $sql_DB);
    if ($stmt = $mysqli->prepare("UPDATE users SET avatar=? WHERE username=?")) {
        $user = $_SESSION['username'];
        $avatar = $resized_file;
        $stmt->bind_param('ss', $avatar, $user);
        $stmt->execute();
        $stmt->close();
        //header('location: profile.html');
        return true;
    }
    $mysqli->close();
    }

// ----------- End Adams Universal Image Resizing Function -----------
// Display things to the page so you can see what is happening for testing purposes
echo "The file named <strong>$username.$fileExt</strong> uploaded successfuly.<br /><br />";
echo "It is <strong>$fileSize</strong> bytes in size.<br /><br />";
echo "It is an <strong>$fileType</strong> type of file.<br /><br />";
echo "The file extension is <strong>$fileExt</strong><br /><br />";
echo "The Error Message output for this upload is: $fileErrorMsg";
?>

The Document edited can be found here source

Trapeze answered 12/1, 2016 at 11:13 Comment(14)
I saw it here https://mcmap.net/q/664757/-android-image-file-sent-to-php-upload-image-file-is-application-octet-stream-type-and-not-image-jpeg But that is only the check if uploaded file is png, jpg or gif, right? I can get that much easier in Laravel with File::mimeType($file). We need here a way to change mime od application/octet-stream to image/jpeg once the file is uploaded from Android appFlamen
but you question is not clear, you only state your problem. I will add/edit my answer nowTrapeze
This is not my question, I am only giving the award for right solution. His question was pretty clear to meFlamen
after you upload the file from the sever then use the code above to convert it.Trapeze
It is still not working. Did you take that from here developphp.com/video/PHP/… If you did, you forgot the line where ak_php_img_lib_1.0.php is included.Flamen
the ak_php_img_lib_1.0.php line does not matter, that is the reason why i put the function in the same file so that you will not have to use additional library and putting it in extra file, if you wish to use GD library i will post the link in my comment nowTrapeze
This where i formatted the code github.com/roicoroy/gallery/blob/master/ak_php_img_lib_1.0.phpTrapeze
Check the answer i just edited now or visit this link: https://mcmap.net/q/664756/-error-when-uploading-file-closedTrapeze
But uploading image is not the problem. The problem is when we get the file on server side with mime application/octet-stream. We need to change it to image/jpeg, if it's possible at all. You just keep writhing the lots of code for image upload and saving it to data base or resize. And you are mentioning Laravel, and I can't see one Laravel specific thing in this code.Flamen
you re not getting the logic, this what happen to above code: when you upload a image into a directory on a server it resized the image and convert it to JPEG, is the same logic that is happen when you re converting image from stringTrapeze
so am expecting you, you format it laravel language that what i meanTrapeze
tell me where you re really getting stock with the code exactly.Trapeze
Let us continue this discussion in chat.Trapeze
@MladenJanjetovic I could have not read the question 100% I have pooled my answer back. thanks letting me know that.Catheterize
S
0

I would try to focus on how you are receiving your file. Try it this way at first:

$data = file_get_contents($_FILES['myphoto']['tmp_name']);
$image = imagecreatefromstring( $data );

it's a cite of answer on this topic.

Image::make(
    imagecreatefromstring(
        file_get_contents($_FILES['myphoto']['tmp_name'])
    )
);

// or maybe
$img = Image::make($_FILES['myphoto']['tmp_name']);

As of for Intervention image manual it should work.;

If it is not an answer, please show me what is code that assigns value to $thumb.

Strike answered 19/1, 2016 at 10:0 Comment(0)
S
0

First of all include Input namespace

use Illuminate\Support\Facades\Input;

then change the value of $thumb variable

$inputFileObj = Input::file('filename_here');
$thumb = $inputFileObj->getRealPath();

then use your code as it is.

Snowplow answered 5/7, 2019 at 13:58 Comment(0)
H
0

You can do this, If the mime type is octet-stream then encode it in the base64 and make image from the string or else make it normally.

$mime_type = $thumb->getMimeType();
$break = explode('/', $mime_type);
if($break[1] == "octet-stream"){
    $imagedata = file_get_contents($thumb);
    $base64 = base64_encode($imagedata);
    Image::make($base64)->resize($this->twidth, $this->theight)->save($this->destination."/".$filename);
}
else{
    Image::make($thumb)->resize($this->twidth, $this->theight)->save($this->destination."/".$filename);
}

I hope it'll be helpful

Hexarchy answered 5/6, 2020 at 6:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.