Изображение base64 в файл изображения с помощью Symfony и VichUploader - PullRequest
0 голосов
/ 12 марта 2019

В Symfony у меня есть сущность Program, которая имеет атрибут image. Загрузка изображений, присвоение им имен и размещение их в нужном каталоге осуществляется с помощью VichUploaderBundle. Сущность выглядит так:

//...

/**
 * NOTE: This is not a mapped field of entity metadata, just a simple property.
 *
 * @Assert\Image(
 *     maxSize="5M",
 *     mimeTypesMessage="The file you tried to upload is not a recognized image file"
 *    )
 * @Vich\UploadableField(mapping="program_image", fileNameProperty="imageName")
 *
 * @var File
 */
private $image;

/**
 * @ORM\Column(type="string", length=191, nullable=true)
 */
private $imageName; 

//...

Теперь я хочу, чтобы изображения обрабатывались до их загрузки, что я сделал с некоторым JS, который возвращает строку base64. Я поместил эту строку в скрытое поле ввода, base64Image. Затем я извлекаю эту строку в моем контроллере и пытаюсь превратить ее в изображение, которое я могу сохранить в своей сущности следующим образом:

if ($form->isSubmitted() && $form->isValid()) {
    $program = $form->getData();

    $base64String = $request->request->get('base64Image');
    $decodedImageString = base64_decode($base64String);

    $program->setImage($decodedImageString);

//etc.....

Программа выполняется с последней строки. $decodedImageString фактически другая строка, которую сначала нужно создать в файл. Я посмотрел в file_put_contents, чтобы создать файл как описатель здесь , но безуспешно.

Имя файла не может быть пустым

Это ошибка, которую я получаю. Также я не знаю, будет ли это работать с VichUploaderBundle, и, возможно, ответ на этот вопрос также устарел. Любые предложения о том, что я мог бы сделать?

Edit: Получил конвертацию и загрузку, работая со следующим кодом:

define('UPLOAD_DIR', 'images/');
$img = $request->request->get('base64Image');
$img = str_replace('data:image/jpeg;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . uniqid() . '.jpeg';
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';

Теперь мне просто нужно как-то загрузить конфигурацию VichUploaderBundle, или, возможно, вообще не использовать ее.

Ответы [ 2 ]

1 голос
/ 13 марта 2019

Попытка решения состоит в том, чтобы сначала преобразовать файл base64 в загруженный файл symfony.

  • Вы определяете эту услугу
<?php

    namespace App\Utils;

    use Symfony\Component\HttpFoundation\File\UploadedFile;

    class UploadedBase64File extends UploadedFile
    {

        public function __construct(string $base64String, string $originalName)
        {
            $filePath = tempnam(sys_get_temp_dir(), 'UploadedFile');
            $data = base64_decode($base64String);
            file_put_contents($filePath, $data);
            $error = null;
            $mimeType = null;
            $test = true;

            parent::__construct($filePath, $originalName, $mimeType, $error, $test);
        }

    }

А затем еще один сервис для извлечения строкового образа pur base64

<?php

    namespace App\Utils;

    class Base64FileExtractor    
    {

        public function extractBase64String(string $base64Content)
        {

            $data = explode( ';base64,', $base64Content);
            return $data[1];

        }

    }
  • И в вашем контроллере вы можете сделать что-то вроде:
    <?php

    namespace App\Controller\Api;

    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Routing\Annotation\Route;
    use App\Utils\UploadedBase64File;
    use App\Utils\Base64FileExtractor;

    class CoreController extends AbstractController
    {
       /**
         * @Route("/images", methods={"POST"}, name="app_add_image")
         */
         public function addImage(Request $request, Base64FileExtractor $base64FileExtractor) 
         {

             //...

             if($form->isSubmitted() && $form->isValid()) {

                  $base64Image = $request->request->get('base64Image');
                  $base64Image = $base64FileExtractor->extractBase64String($base64Image);
                  $imageFile = new UploadedBase64File($base64Image, "blabla");
                  $program->setImage($imageFile);

                  //... 
                  // Do thing you want to do
             }
             // Do thing you want to do

         }
   }
  • Метод setImage в вашей программной сущности может быть что-то вроде
       /**
         * @param null|File $image
         * @return Program
         */
        public function setImage(?File $image): Program
        {
            $this->image = $image;

            if($this->image instanceof UploadedFile) {
                $this->updatedAt = new \DateTime('now');
            }

            return $this;
        }

Если вы хотите проверить изображение, вы должны установить его непосредственно после обработки формы, и проверка будет выполняться в обычном режиме. Я надеюсь, что эта идея может помочь вам.

0 голосов
/ 12 марта 2019

Вы пытаетесь сохранить изображение целиком в setImage.
И все же, здесь вам нужно строковое значение.

Вот как я это делаю.

$ext='.png';
$fileName='file_name'.$ext;

$base64=str_replace('data:image/png;base64,', '', $base64);

$file=fopen('path_to_upload_dir'.$fileName, 'wb');
fwrite($file, base64_decode($base64));
fclose($file);

$program->setImage($fileName);
...