Git Product home page Git Product logo

Comments (9)

Danack avatar Danack commented on August 19, 2024

I'll have a look - I can't make any promises.

You might be able to find something that achieves that effect on
http://www.fmwconcepts.com/imagemagick/

from imagickdemos.

vtjiles avatar vtjiles commented on August 19, 2024

Thanks, and no worries if you can't come up with something. The examples have been great in helping me understand what the different methods actually do.

I had looked at that site and the feathering actually darkened the image a good bit so I couldn't use it. I didn't test out others though.

Shortly after putting this up here (despite searching for two days) I came across http://tech.natemurray.com/2007/12/convert-white-to-transparent.html which is perfect for what I'm looking to do. I tweaked it so the color is dynamic and it fills in all the sections instead of the outside ones so I think I can run with it. A php port would be awesome though so that files don't need to keep being written.

Appreciate the response!

from imagickdemos.

Danack avatar Danack commented on August 19, 2024

The code below produces an image very much like:
backgroundmasking

It's basically the same technique as the link, except it also attempts to get rid of the white outline.

    //Load the image
    $imagick = new \Imagick(realpath('images/chair.jpeg'));

    $backgroundColor = "rgb(255, 255, 255)";
    $fuzzFactor = 0.1;

    // Create a copy of the image, and paint all the pixels that
    // are the background color to be transparent
    $outlineImagick = clone $imagick;    
    $outlineImagick->transparentPaintImage(
        $backgroundColor, 0, $fuzzFactor * \Imagick::getQuantum(), false
    );

    // Copy the input image
    $mask = clone $imagick;
    // Deactivate the alpha channel if the image has one, as later in the process 
    // we want the mask alpha to be copied from the colour channel to the src 
    // alpha channel. If the mask image has an alpha channel, it would be copied
    // from that instead of from the colour channel. 
    $mask->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);
    //Convert to gray scale to make life simpler
    $mask->transformImageColorSpace(\Imagick::COLORSPACE_GRAY);

    // DstOut does a "cookie-cutter" it leaves the shape remaining after the
    // outlineImagick image, is cut out of the mask. 
    $mask->compositeImage(
        $outlineImagick,
        \Imagick::COMPOSITE_DSTOUT,
        0, 0
    );

    // The mask is now black where the objects are in the image and white
    // where the background is.
    // Negate the image, to have white where the objects are and black for
    // the background
    $mask->negateImage(false);

    $fillPixelHoles = false;

    if ($fillPixelHoles == true) {
        // If your image has pixel sized holes in it, you will want to fill them
        // in. This will however also make any acute corners in the image not be
        // transparent.

        // Fill holes - any black pixel that is surrounded by white will become
        // white
        $mask->blurimage(2, 1);
        $mask->whiteThresholdImage("rgb(10, 10, 10)");

        // Thinning - because the previous step made the outline thicker, we
        // attempt to make it thinner by an equivalent amount.
        $mask->blurimage(2, 1);
        $mask->blackThresholdImage("rgb(255, 255, 255)");
    }

    //Soften the edge of the mask to prevent jaggies on the outline.
    $mask->blurimage(2, 2);

    // We want the mask to go from full opaque to fully transparent quite quickly to 
    // avoid having too many semi-transparent pixels. sigmoidalContrastImage does this
    // for us. Values to use where determined empirically.
    $contrast = 15;
    $midpoint = 0.7 * \Imagick::getQuantum();
    $mask->sigmoidalContrastImage(true, $contrast, $midpoint);

    // Copy the mask into the opacity channel of the original image.
    // You are probably done here if you just want the background removed.
    $imagick->compositeimage(
        $mask,
        \Imagick::COMPOSITE_COPYOPACITY,
        0, 0
    );

    // To show that the background has been removed (which is difficult to see
    // against a plain white webpage) we paste the image over a checkboard
    // so that the edges can be seen.

    // Create the check canvas
    $canvas = new \Imagick();
    $canvas->newPseudoImage(
        $imagick->getImageWidth(),
        $imagick->getImageHeight(),
        "pattern:checkerboard"
    );

    // Copy the image with the background removed over it.
    $canvas->compositeimage($imagick, \Imagick::COMPOSITE_OVER, 0, 0);

    //Output the final image
    $canvas->setImageFormat('png');
    header("Content-Type: image/png");
    echo $canvas->getImageBlob();

from imagickdemos.

vtjiles avatar vtjiles commented on August 19, 2024

Looks great, but having some issues with darker/black items. Any thoughts?

Really appreciate you putting this together. A quick test shows it's running 15x faster than the method I am currently using!

from imagickdemos.

Danack avatar Danack commented on August 19, 2024

Can you give an example image that doesn't work as well?

from imagickdemos.

vtjiles avatar vtjiles commented on August 19, 2024

Here is one I had trouble with. I should also note I must have an older version of the library since I don't have getQuantum and instead used getQuantumRange()['quantumRangeLong']. Not sure if there were other changes/improvements across versions.

image

from imagickdemos.

Danack avatar Danack commented on August 19, 2024

I've updated the code above, the extra line is:
$mask->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);

As the source image has an alpha channel, which was mucking up the $imagick->compositeimage($mask, \Imagick::COMPOSITE_COPYOPACITY, 0, 0); as it was copying the alpha from the alpha channel rather than the colour channel as intended.

I should also note I must have an older version of the library

Yeah.....as I'm the maintainer of the library I tend to be running the latest version. Compiling the extension is really quite easy and means you never have to wait to get stuff...

from imagickdemos.

vtjiles avatar vtjiles commented on August 19, 2024

Worked great. Thanks so much for putting this together!

from imagickdemos.

Danack avatar Danack commented on August 19, 2024

No problem, making pretty pictures is far more interesting than writing documentation...

from imagickdemos.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.