Search code examples
phplaravelphp-gdintervention

Intervention black borders around cropped png image


I'm using Intervention in a laravel app (as everyone does) and have come across an issue where black borders are being applied around an image when cropped, like so:

enter image description here

Seems odd that it's preserving the transparency of the image file, and then filling the rest of the image with black.

My method for cropping and saving these images is as follows:

/**
 * Accept parameter array (
    '_token' => 'E1seBDvsEBj1aNpLmenIKkAoNSKct878tqnIwOQO',
    'x' => 55,
    'y' => '30',
    'width' => '200',
    'height' => '200',
    'filename' => '1_somerandomhash.jpg',
    )
 *
 * Move the given filename from TMP_ORG_LOGOS to ORGANIZATION_LOGOS_DIRECTORY, apply
 * cropped dimensions, rename to organization slug name plus small random hash, return
 * true or false
 *
 * @param array $params
 * @return bool
 */
public function saveLogo(int $userId, array $params) : bool {
    try{
        $org = $this->userService->getUserDefaultOrg($userId);
        $newImageName = $org->slug . '-' . uniqid() . '.png';
        Image::make(getenv('TMP_ORG_LOGOS') . $params['filename'])
            ->crop(round($params['width']), round($params['height']),
                round($params['x']), round($params['y']))
            ->save(getenv('ORGANIZATION_LOGOS_DIRECTORY') . $newImageName, 100);
        $org->logo = $newImageName;
        $org->save();
        return true;
    } catch (\Exception $e){
        return false;
    }
}

Has anyone run across this before? Is there a way within intervention to make these black borders transparent?

EDIT

I should also mention that intervention is using php's default GD library for image manipulation.


Solution

  • Was able to resolve this by creating a separate image using intervention's canvas() method. I then used trim() on the cropped image to remove the surrounding borders, and inserted that image into the center of the new canvas image. A little convoluted, and slow (3-4 seconds on the server) but it solves the problem. Still open to better solutions (if any exist).

    public function saveLogo(int $userId, array $params) : bool {
        try{
            $org = $this->userService->getUserDefaultOrg($userId);
            $newImageName = $org->slug . '-' . uniqid() . '.png';
    
            $cropped = Image::make(getenv('TMP_ORG_LOGOS') . $params['filename'])
                ->crop(round($params['width']), round($params['height']),
                    round($params['x']), round($params['y']))
                ->encode('png', 100)->trim();
    
            $canvas = \Image::canvas(round($params['width']), round($params['height']));
            $canvas->insert($cropped, 'center');
            $canvas->save(getenv('ORGANIZATION_LOGOS_DIRECTORY') . $newImageName, 100);
    
            $org->logo = $newImageName;
            $org->save();
    
            return true;
        } catch (\Exception $e){
            return false;
        }
    }