Ошибка записи в файл изображения из PHP - PullRequest
2 голосов
/ 15 июля 2011

Я пытаюсь записать файл изображения с большого двоичного объекта.

 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).

BLOB отображается правильно, если я создаю img и устанавливаю его src = blob

Ниже приведен первый фрагмент BLOB:

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

Ответы [ 4 ]

8 голосов
/ 15 июля 2011

Ваш "Blob" действительно URI данных :

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

Так как вам нужна только часть декодированных данных, вам нужно сделать

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

Но так как PHP изначально поддерживает data: // streams, вы также можете сделать это (спасибо @NikiC)

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

Если вышеперечисленное не работает, вы можете попробовать с GDlib:

imagejpg(
    imagecreatefromstring(
        base64_decode( 
            str_replace('data:image/jpeg;base64,', '', $blob)
        )
    ), 
    'image.jpg'
);
0 голосов
/ 15 июля 2011

Эта функция сохраняет данные в файл:

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 . '" />';
0 голосов
/ 15 июля 2011

Если это действительно большой двоичный объект, вы можете попробовать использовать режим "wb" в качестве второго параметра в вызове fopen ().

РЕДАКТИРОВАТЬ : Вы также можете рассмотреть возможность использования file_put_contents () , который является бинарно-безопасным.

0 голосов
/ 15 июля 2011

Если это элемент управления загрузкой файлов, $_POST не будет содержать информацию.Вы ищете для обработки загрузки файлов с $_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
  }
...