从 PHP 写入图像文件时出错

发布于 2024-11-23 15:14:02 字数 642 浏览 2 评论 0 原文

我正在尝试从 blob 写入图像文件。

 if($_POST['logoFilename'] != 'undefined'){
  $logoFile = fopen($_POST['logoFilename'], 'w') or die ("Cannot create ".$_POST['logoFilename']);

  fwrite($logoFile, $_POST['logoImage']);

  fclose($logoFile);
}

在前面的代码片段中,$_POST['logoImage'] 是一个 BLOB。文件已正确写入根目录,但无法打开该文件。在 ubuntu 11.04 中,我收到以下错误:

Error interpreting JPEG image file (Not a JPEG file: starts with 0x64 0x61).

如果我创建 img 并设置其 src=blob,则 BLOB 会正确显示

下面包含 BLOB 的第一个片段:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEBLAEsAAD/2wBDAAgGBgcGBQgHBwcJCQ

I am attempting to write to an image file from a blob.

 if($_POST['logoFilename'] != 'undefined'){
  $logoFile = fopen($_POST['logoFilename'], 'w') or die ("Cannot create ".$_POST['logoFilename']);

  fwrite($logoFile, $_POST['logoImage']);

  fclose($logoFile);
}

In the previous code snippet, $_POST['logoImage'] is a BLOB. The file is correctly written to the root directory, however the file cannot be opened. In ubuntu 11.04 I receive the following error:

Error interpreting JPEG image file (Not a JPEG file: starts with 0x64 0x61).

The BLOB does correctly display if I create an img and set its src=blob

Included below is the first snippet of the BLOB:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEBLAEsAAD/2wBDAAgGBgcGBQgHBwcJCQ

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你好,陌生人 2024-11-30 15:14:03

您的“Blob”确实是一个Data URI

data:[<MIME-type>][;charset=<encoding>][;base64],<data>

由于您只想要解码后的数据部分,因此您必须这样做

file_put_contents(
    'image.jpg',
    base64_decode( 
        str_replace('data:image/jpeg;base64,', '', $blob)
    )
);

,但是由于 PHP 本身支持 data:// 流,你也可以(感谢@NikiC)

file_put_contents('image.jpg', file_get_contents($blob));

如果上面的方法不起作用,你可以尝试使用GDlib:

imagejpg(
    imagecreatefromstring(
        base64_decode( 
            str_replace('data:image/jpeg;base64,', '', $blob)
        )
    ), 
    'image.jpg'
);

Your "Blob" is really a Data URI:

data:[<MIME-type>][;charset=<encoding>][;base64],<data>

Since you only want the decoded data part, you have to do

file_put_contents(
    'image.jpg',
    base64_decode( 
        str_replace('data:image/jpeg;base64,', '', $blob)
    )
);

But since PHP natively supports data:// streams, you can also do (thanks @NikiC)

file_put_contents('image.jpg', file_get_contents($blob));

If the above doesnt work, you can try with GDlib:

imagejpg(
    imagecreatefromstring(
        base64_decode( 
            str_replace('data:image/jpeg;base64,', '', $blob)
        )
    ), 
    'image.jpg'
);
小…楫夜泊 2024-11-30 15:14:03

如果它确实是一个 blob,您可能需要尝试使用模式“wb”作为 fopen() 调用的第二个参数。

编辑:您也可以考虑使用 file_put_contents(),它是二进制的 -安全的。

If it's really a blob, you might want to trying using mode "wb" as the second parameter to your fopen() call.

EDIT: You might also consider just using file_put_contents(), which is binary-safe.

笔落惊风雨 2024-11-30 15:14:03

如果是文件上传控件,则$_POST不会包含该信息。您正在寻找使用 处理文件上传 http://php.net/manual/en/reserved.variables.files.php" rel="nofollow noreferrer">$_FILES。 (更具体地说,move_uploaded_file

鉴于新的更新,请尝试以下操作:

  // 
  // Export a image blob to a file using either the specific image name
  // @blob     : The actual image blob
  // @fileName : Can be the explicit name (with an extension) or this can be
  //             just a generic file name and the extension (based on data
  //             type) will be appended automatically. This can also include
  //             path information.
  // Exmaples:
  //   storeBlob('data:image/png;base64,...', 'myimage');      ::  saves as myimage.png
  //   storeBlob('data:image/jpg;base64,...', 'img/new.jpg');  ::  saves as img/new.jpg
  function storeBlob($blob, $fileName)
  {
    $blobRE = '/^data:((\w+)\/(\w+));base64,(.*)$/';
    if (preg_match($blobRE, $blob, $m))
    {
      $imageName = (preg_match('/\.\w{2,4}$/', $fileName) ? $fileName : sprintf('%s.%s', $fileName, $m[3]));
      
      return file_put_contents($imageName,base64_decode($m[4]));
    }
    return false; // error
  }

If it's a file upload control, $_POST won't contain the information. You're looking for handling file uploads with $_FILES. (And more specifically, move_uploaded_file)

Given the new update, try the following:

  // 
  // Export a image blob to a file using either the specific image name
  // @blob     : The actual image blob
  // @fileName : Can be the explicit name (with an extension) or this can be
  //             just a generic file name and the extension (based on data
  //             type) will be appended automatically. This can also include
  //             path information.
  // Exmaples:
  //   storeBlob('data:image/png;base64,...', 'myimage');      ::  saves as myimage.png
  //   storeBlob('data:image/jpg;base64,...', 'img/new.jpg');  ::  saves as img/new.jpg
  function storeBlob($blob, $fileName)
  {
    $blobRE = '/^data:((\w+)\/(\w+));base64,(.*)$/';
    if (preg_match($blobRE, $blob, $m))
    {
      $imageName = (preg_match('/\.\w{2,4}$/', $fileName) ? $fileName : sprintf('%s.%s', $fileName, $m[3]));
      
      return file_put_contents($imageName,base64_decode($m[4]));
    }
    return false; // error
  }
梦旅人picnic 2024-11-30 15:14:03

此函数会将数据 uri 保存到文件:

function saveDataUri($blob, $filename = null) 
{

    // generate unique name basing on content
    if (empty($filename)) {
        $filename = md5($blob);
    }

    // parse data URI
    $semiPos = strpos($blob, ';', 5);
    $comaPos = strpos($blob, ',', 5);
    $mime = substr($blob, 5, $semiPos - 5);
    $data = substr($blob, $comaPos + 1);

    $isEncoded = strpos(substr($blob, $semiPos, $comaPos), 'base64');

    if ($isEncoded) {
        $data = base64_decode($data);
    }


    // save image data to file
    switch ($mime) {
           case 'image/png':
                $ext = 'png';
            break;
           case 'image/gif':
                $ext = 'gif';
                break;
           case 'image/jpg':
           case 'image/jpeg':
           default:
                $ext = 'jpg';
                break;  
    }

    $outFile = $filename . '.' . $ext;
    $funcName = 'image' . $ext;
    $result = $funcName(imagecreatefromstring($data), $outFile);

    if ($result) {

        return $outFile;
    }

    return $result;
}

在您的情况下使用:

// some_validation($_POST);
$filename = saveDataUri($_POST['logoImage']);
echo '<img src="' . $filename . '" alt="' . $filename . '" />';

This function will save data uri to file:

function saveDataUri($blob, $filename = null) 
{

    // generate unique name basing on content
    if (empty($filename)) {
        $filename = md5($blob);
    }

    // parse data URI
    $semiPos = strpos($blob, ';', 5);
    $comaPos = strpos($blob, ',', 5);
    $mime = substr($blob, 5, $semiPos - 5);
    $data = substr($blob, $comaPos + 1);

    $isEncoded = strpos(substr($blob, $semiPos, $comaPos), 'base64');

    if ($isEncoded) {
        $data = base64_decode($data);
    }


    // save image data to file
    switch ($mime) {
           case 'image/png':
                $ext = 'png';
            break;
           case 'image/gif':
                $ext = 'gif';
                break;
           case 'image/jpg':
           case 'image/jpeg':
           default:
                $ext = 'jpg';
                break;  
    }

    $outFile = $filename . '.' . $ext;
    $funcName = 'image' . $ext;
    $result = $funcName(imagecreatefromstring($data), $outFile);

    if ($result) {

        return $outFile;
    }

    return $result;
}

Usage in your case:

// some_validation($_POST);
$filename = saveDataUri($_POST['logoImage']);
echo '<img src="' . $filename . '" alt="' . $filename . '" />';
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文