【问题标题】:base64 image to image file with Symfony and VichUploader使用 Symfony 和 VichUploader 的 base64 图像到图像文件
【发布时间】:2019-08-03 01:47:39
【问题描述】:

在 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; 

//...

现在我希望在上传图像之前对其进行处理,我已经使用一些返回 base64 字符串的 JS 来完成。我将此字符串放在隐藏的输入字段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 以创建一个文件作为描述者here,但没有运气。

文件名不能为空

是我收到的错误。另外我不知道这是否适用于VichUploaderBundle,也许该问题的答案也已过时。关于我能做什么的任何建议?

编辑: 使用以下代码进行转换和上传:

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 配置,或者可能不完全使用它。

【问题讨论】:

  • 我在此主题converting-any-base64-file-to-a-file-and-moving-to-the-targeted-path-in-php-symfony 中发布了答案。我希望这可以让您了解如何使用 vichuploaderbundle 进行管理。
  • 然后你也可以通过这个话题convert-base64-string-to-an-image-file得到这个答案。这可以帮助您提取 pur base64 图像,并结合我上面的答案使用 vichuploaderbundle 进行管理。
  • @williambridge,我尝试了你写下的一切。当我尝试使用$program->saveImage() 保存图像时,我仍然遇到问题。使用tempnam() 创建的临时文件不会被识别为文件,而是被识别为字符串。我尝试将扩展名更改为 .jpeg,但这也不起作用。

标签: symfony symfony4 vichuploaderbundle


【解决方案1】:

一种解决方案的尝试是首先将base64文件转换为symfony uploadFile。

  • 您定义此服务
<?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

         }
   }
  • 您的 Program 实体中的方法 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;
        }

如果要对图片进行验证,应该在处理完表单后直接设置,并且会习惯性的进行验证。 我希望这个想法可以帮助你。

【讨论】:

  • 确实很有帮助。使用UploadedFile 时,一个关键部分是$test = true;。我还没有完全达到我想要的位置,但这让我走上了正确的轨道。
【解决方案2】:

您正在尝试将整个图像存储到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);

【讨论】:

  • 我在使用这个时遇到了一堆错误。首先,方法 uuid1 无法识别。但即使我手动为文件命名,我也会收到一个错误,即未定义“ul_path”。
  • 欣赏它。我用一些类似的方法进行了管理(见编辑)。现在我只需要弄清楚如何使用 VichUploaderBundle。
猜你喜欢
  • 2020-02-03
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
  • 2016-03-24
  • 2015-05-22
  • 2018-07-12
  • 2020-04-17
  • 2011-03-17
相关资源
最近更新 更多