Search code examples
phpdropzone.jslaravel-5.5watermarkintervention

Add watermarks to multiple images using Dropzone.js and Laravel 5.5


I have a form where a user can upload multiple images with Dropzone.js and then I store those images in the database and in the public/images folder.

But what I need is to add a watermark to all of these images before I save them in the public/images directory, because these images will show in the front-end as "preview" images.

I found documentation on how to add watermarks using Intervention Image here.

But I just cant figure out how I would proceed in adding that in my current setup.

Here is my form with the script:

 <div id="file-preview_images" class="dropzone"></div>

 <script>
    let dropPreview = new Dropzone('#file-preview_images', {
        url: '{{ route('upload.preview.store', $file) }}',
        headers: {
            'X-CSRF-TOKEN': document.head.querySelector('meta[name="csrf-token"]').content
        }
    });

    dropPreview.on('success', function(file, response) {
        file.id = response.id;
    });
</script>

$file variable is when a user clicks on create a new File, it creates a new File with a unique identifier before its even saved. A file can have many uploads.

Here is my store method:

public function store(File $file, Request $request) {

        // Make sure the user owns the file before we store it in database.
        $this->authorize('touch', $file);

        // Get the file(s)
        $uploadedFile = $request->file('file');

        $upload = $this->storeUpload($file, $uploadedFile);

        $request->file( 'file' )->move(
            base_path() . '/public/images/previews/', $upload->filename
        );

        return response()->json([
            'id' => $upload->id
        ]);
}



protected function storeUpload(File $file, UploadedFile $uploadedFile) {

        // Make a new Upload model
        $upload = new Upload;

        // Fill the fields in the uploads table
        $upload->fill([
            'filename' => $uploadedFile->getClientOriginalName(),
            'size' => $uploadedFile->getSize(),
            'preview' => 1
        ]);

        // Associate this upload with a file.
        $upload->file()->associate($file);

        // Associate this upload with a user
        $upload->user()->associate(auth()->user());

        // Save the file
        $upload->save();

        return $upload;
}

All of that works as intended, I just need to add watermarks to each of these images, which I'm having trouble with.

I already saved a watermark image in public/images/shutterstock.png


Solution

  • I figured it out. This is what I had to do:

    public function store(File $file, Request $request) {
    
            // Make sure the user owns the file before we store it in database.
            $this->authorize('touch', $file);
    
            // Get the file(s)
            $uploadedFile = $request->file('file');
    
            $upload = $this->storeUpload($file, $uploadedFile);
    
            // Get the image, and make it using Image Intervention
            $img = Image::make($request->file('file'));
    
            // Insert the image above with the watermarked image, and center the watermark
            $img->insert('images/home/shutterstock.png', 'center');
    
            // Save the image in the 'public/images/previews' directory
            $img->save(base_path() . '/public/images/gallery/pre/'.$upload->filename);      
    
            return response()->json([
                'id' => $upload->id
            ]);
        }
    

    And on the "storeUpload" method, changed the 'filename' too:

    $upload->fill([
        'filename' => $file->identifier.'-'.uniqid(10).$uploadedFile->getClientOriginalName(),
        'size' => $uploadedFile->getSize(),
        'preview' => 1
    ]);