phpsymfonysymfony5vichuploaderbundle

How to use an image created with "imagecreate()" with VichUploader?


I want to generate an image from the PHP function imagecreate() and then persist it thanks to VichUploaderBundle. For you information, I am using Symfony 5.1

Here is my test code I use in my controller:

$im = imagecreate(110, 20);
$background_color = imagecolorallocate($im, 0, 0, 0);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5,  "A Simple Text String", $text_color);
imagepng($im);

$entity->setImageFile($im);
// imagedestroy($im);
$this->getDoctrine()->getManager()->flush();

The code to generate images thanks to PHP comes from here

Then I get this error:

Argument 1 passed to setImageFile() must be an instance of Symfony\Component\HttpFoundation\File\File or null, resource given

setImageFile() is the basic function to implement when using VichUploader

/**
 * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile|null $image_file
 */
public function setImageFile(?File $image_file = null): self
{
    $this->image_file = $image_file;
    if (null !== $image_file) {
        // It is required that at least one field changes if you are using doctrine
        // otherwise the event listeners won't be called and the file is lost
        $this->updated_at = new \DateTime('now');
    }

    return $this;
}

Solution

  • setImageFile() expects a File instance, and you are attempting to pass it a resource, exactly as the error says..

    What you need is to store imagepng() output in a physical file, and use that to create a new instance of File which you'll pass to setImageFile().

    A simple implementation:

    $filename = bin2hex(random_bytes(7);
    $filePath = sys_get_temp_dir() . "/$filename.png";
    
    $im               = imagecreate(110, 20);
    $background_color = imagecolorallocate($im, 0, 0, 0);
    $text_color       = imagecolorallocate($im, 233, 14, 91);
    imagestring($im, 1, 5, 5,  "A Simple Text String", $text_color);
    
    imagepng($im, $filePath);
    
    $entity->setImageFile(new UploadedFile($filePath, $filename, 'image/png'));
    

    I'm simply storing the created image on the system temporary dir, and choosing a random string as filename. You may want to adjust any of this to your application needs.