干预图像 - 如何上传 MIME 类型的图像:application/octet-stream
Posted
技术标签:
【中文标题】干预图像 - 如何上传 MIME 类型的图像:application/octet-stream【英文标题】:Intervention Image - how to upload images with MIME type: application/octet-stream 【发布时间】:2015-02-17 00:31:26 【问题描述】:我使用 Laravel 框架和干预图像库来上传和处理我页面上的图像。一切正常,直到我尝试更新从移动设备或相机拍摄的 .jpg 图像。这些图像的 MIME 类型为 application/octet-stream
而不是 image/jpeg
。当我尝试使用此命令上传图片时:
Image::make($thumb)->resize($this->twidth, $this->theight)->save($this->destination."/".$filename);
我得到错误:
Unable to read image from file
一个不舒服的解决方案是在 MS Paint 中打开图像并重新保存它们,这会将 MIME 类型更改为“图像/jpeg”并使其可以上传。但我想不惜一切代价避开这个解决方案。
编辑:
我试图通过这个命令修复它:
$img = imagecreatefromstring($thumb);
但它返回错误:imagecreatefromstring(): Empty string or invalid image
有没有办法处理这种类型的图像?
【问题讨论】:
Did you search SO before asking? 是的,我找到了,但没有找到这个答案 顺便说一句,它对我不起作用 我在从 android 上传时遇到了同样的问题。当我尝试使用imagecreatefromstring(//UPLOAD FILE CONTENTS//)
时,我收到 imagecreatefromstring(): gd 警告:内存分配乘法的一个参数为负数或零,操作正常失败
$thumb 里面有什么,一个带有 $path 或 FileUpload 对象的简单字符串?
【参考方案1】:
你可以试一试并将其转换为 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
更多文档。在此访问此链接:Source document
如果你想走极端,可以尝试将其格式化为 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;
?>
要将图像转换为 JPEG 试试这个:
<?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";
?>
以上代码的更清晰的文档
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";
?>
编辑的文档可以在这里找到source
【讨论】:
我在这里看到了***.com/a/11316048/1090395 但这只是检查上传的文件是png、jpg还是gif,对吗?我可以使用 File::mimeType($file) 在 Laravel 中更轻松地做到这一点。从 Android 应用上传文件后,我们需要一种方法将 mime od application/octet-stream 更改为 image/jpeg 但你的问题不清楚,你只陈述你的问题。我现在将添加/编辑我的答案 这不是我的问题,我只是奖励正确的解决方案。他的问题对我来说很清楚 从服务器上传文件后,使用上面的代码进行转换。 它仍然无法正常工作。你是从这里得到的吗developphp.com/video/PHP/… 如果你这样做了,你忘记了包含 ak_php_img_lib_1.0.php 的行。【参考方案2】:我会尽量关注您接收文件的方式。先这样试试吧:
$data = file_get_contents($_FILES['myphoto']['tmp_name']);
$image = imagecreatefromstring( $data );
这是对this topic 的引用。
Image::make(
imagecreatefromstring(
file_get_contents($_FILES['myphoto']['tmp_name'])
)
);
// or maybe
$img = Image::make($_FILES['myphoto']['tmp_name']);
对于Intervention image manual,它应该可以工作。;
如果不是答案,请告诉我将值分配给$thumb
的代码是什么。
【讨论】:
【参考方案3】:首先包括输入命名空间
use Illuminate\Support\Facades\Input;
然后改变$thumb变量的值
$inputFileObj = Input::file('filename_here');
$thumb = $inputFileObj->getRealPath();
然后按原样使用您的代码。
【讨论】:
【参考方案4】:你可以这样做,如果 mime 类型是 octet-stream
然后在 base64 中编码并从字符串中制作图像,否则正常制作。
$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);
希望对你有帮助
【讨论】:
【参考方案5】:检查 php.ini 中的 upload_max_filesize。这是我的理由。
【讨论】:
谢谢,我也遇到了这个问题,并通过增加上传最大文件大小来解决。【参考方案6】:好吧,在这种情况下,您可以删除 Laravel 验证规则 mimes,而可以使用 PHP 通过其扩展名来验证图像。
您的验证规则将如下所示。
$request->validate([
'image' => 'required',
]);
使用文件扩展名验证图像将如下所示
if (! in_array($request->file('image')->clientExtension(), ['jpg', 'jpeg', 'png']))
// not a valid image
【讨论】:
以上是关于干预图像 - 如何上传 MIME 类型的图像:application/octet-stream的主要内容,如果未能解决你的问题,请参考以下文章
使用图像干预的多图像上传。我尝试上传多张图片但无法上传,因为我不知道如何,任何帮助将不胜感激
如何使用干预图像laravel将webp图像转换为jpeg或png
在使用 Shrine 和 Rails 加密之前为图像文件设置 mime 类型