PDFlib Cookbook

cookbook

color/softmask_effects updated

Create a soft mask based on arbitrary geometric objects.

Download PHP Code  Switch to Java Code  Show Output 

<?php
/*
 * Soft mask effects:
 * Create a template as luminosity soft mask in an extended gstate. These
 * soft masks are very powerful and more general than simple clipping operations.
 * 
 * The following soft mask effects are demonstrated:
 * - For comparison the original image is shown first
 * - Colorize image with soft mask: color appears in the light areas
 * - Invert and colorize image: color appears in the dark areas
 * - Apply opacity gradient to an image (fade-out effect)
 *
 * Required software: PDFlib/PDFlib+PDI/PPS 10
 * Required data: none
 */

/* This is where the data files are. Adjust if necessary. */
$searchpath = "../input";
$outfile = "";
$imageFilename = "nesrin.jpg";
$title = "Soft mask effects";

$page_size = 400;
$border = 20;
$exitcode = 0;


try {
    $font_options =
    "fontname=NotoSerif-Regular fontsize=12 leading=125% alignment=center fillcolor=black";

    $p = new pdflib();
    
    $p->set_option("searchpath={" . $searchpath . "}");

    /* This means that errors throw an exception */
    $p->set_option("errorpolicy=exception");

    $p->begin_document($outfile, "");

    $p->set_info("Creator", "PDFlib Cookbook");
    $p->set_info("Title", $title);

    /* Load content which will be colorized; this could be a raster
    * image, SVG graphics, PDF page or other contents.
    */
    $image = $p->load_image("auto", $imageFilename, "");
    
    /*
    * The image is placed centered on the page, the fitbox being
    * half the width and height of the page.
    */
    $image_box_llx = $page_size / 4;
    $image_box_lly = $page_size / 4;
    $image_fit_options = "boxsize={" . ($page_size / 2) . " "
        . ($page_size / 2) . "} fitmethod=meet position=center";
    
    // Determine position and size of the placed image
    $image_width = $p->info_image($image, "width", $image_fit_options);
    
    $image_llx = $image_box_llx + $p->info_image($image, "x1", $image_fit_options);
    $image_lly = $image_box_lly + $p->info_image($image, "y1", $image_fit_options);
    
    // Retrieve path handle for the bounding box of the placed object.
    // This is convenient for filling the path with a single command.
    $bbox = $p->info_image($image, "boundingbox", $image_fit_options);


    // ------------------- For comparison: the original image
    $p->begin_page_ext($page_size, $page_size, "");
    
    $textflow = $p->create_textflow(
        "For comparison: the original image", $font_options);
    
    $p->fit_image($image, $image_box_llx, $image_box_lly, $image_fit_options);
    
    $p->fit_textflow($textflow,
        $border, $border, $page_size - $border, $page_size / 5,
        "fitmethod=auto");
    $p->delete_textflow($textflow);
    
    $p->end_page_ext("");

    /*
    * Create a template that will be used for the soft mask gstate.
    * 
    * The soft mask is defined by the image contents, where light
    * areas let the fill color pass through, while dark areas block
    * the fill color. You can add arbitrary content (e.g. text)
    * to the soft mask template.
    * 
    * This technique can be used to create clipping areas by
    * adding multiple areas, which is not possible with the clip()
    * operation.
    * 
    * Templates which will be used as softmasks must be created with
    * a transparency group and a suitable colorspace.
    */
    $templ = $p->begin_template_ext($page_size, $page_size, "transparencygroup={colorspace=sRGB}");
    // Place the image which will act as soft mask
    $p->fit_image($image, $image_box_llx, $image_box_lly, $image_fit_options);
    $p->end_template_ext(0, 0);

    // ------------------- Colorize image with soft mask: color appears in the light areas
    $p->begin_page_ext($page_size, $page_size, "");
    
    // Create a gstate with luminosity soft mask based on the template;
    // Initialize transparent background.
    $gstate_softmask = $p->create_gstate(
        "softmask={template=" . $templ . " type=luminosity backdropcolor={0 0 0.000001} }");
    
    // Fill the bounding box with color while applying the gstate
    $p->draw_path($bbox, $image_box_llx, $image_box_lly, "fill fillcolor=blue gstate=" . $gstate_softmask);
    
    $textflow = $p->create_textflow(
        "Colorize image with soft mask: color appears in the light areas. " .
        "Since dark areas block the color the image appears inverted.",
        $font_options);
    
    $p->fit_textflow($textflow,
        $border, $border, $page_size - $border, $page_size / 5,
        "fitmethod=auto");
    $p->delete_textflow($textflow);
    
    $p->end_page_ext("");


    // ----------- Invert and colorize image: color appears in the dark areas
    $p->begin_page_ext($page_size, $page_size, "");
    
    // Create a gstate with luminosity soft mask based on the template
    // Initialize transparent background and invert black/white polarity
    $gstate_softmask = $p->create_gstate(
        "softmask={type=luminosity template=" . $templ . " backdropcolor=transparent invert}");

    // Fill the bounding box with color while applying the gstate
    $p->draw_path($bbox, $image_box_llx, $image_box_lly, "fill fillcolor=blue gstate=" . $gstate_softmask);

    $textflow = $p->create_textflow(
        "Colorize image with inverted softmask: color appears in the dark areas.",
        $font_options);
    
    $p->fit_textflow($textflow,
        $border, $border, $page_size - $border, $page_size / 5,
        "fitmethod=auto");
    $p->delete_textflow($textflow);

    $p->end_page_ext("");

    
    // ----- Apply opacity gradient to an image (fade-out effect)
    $p->begin_page_ext($page_size, $page_size, "");

    // Create template and fill it with axial shading from black to white.
    // Templates which will be used as softmasks must be created with
    // a transparency group and a suitable colorspace.

    $templ = $p->begin_template_ext($page_size, $page_size, "transparencygroup={colorspace=sRGB}");

    /*
     * The axial shading reaches full white a little bit before the
     * right border of the image and extends beyond that point with
     * full white so we get the image clearly without any transparency
     * at the right edge.
     */
    $sh = $p->shading("axial",
            $image_llx, $image_lly,
            $image_llx + 0.9 * $image_width, $image_lly,
            0.0, 0.0, 0.0, 0.0, "startcolor={gray 0} endcolor={gray 1} extend1=true");

    $shp = $p->shading_pattern($sh, "");
    
    // Fill the bounding box with the shading pattern
    $p->draw_path($bbox, $image_box_llx, $image_box_lly, "fill fillcolor={pattern " . $shp . "}");
    
    $p->end_template_ext(0, 0);
    
    // Create a gstate with luminosity soft mask based on the template
    // Initialize transparent background
    $gstate_softmask = $p->create_gstate(
        "softmask={template=" . $templ . " type=luminosity backdropcolor=transparent}");

    // Place the image while applying the gstate
    $p->fit_image($image, $image_box_llx, $image_box_lly, $image_fit_options . " gstate=" . $gstate_softmask);
    
    $textflow = $p->create_textflow(
        "Apply opacity gradient to an image (fade-out effect). " .
        "Dark gradient areas at the left block the color, making " .
        "the image transparent.",
        $font_options);
    
    $p->fit_textflow($textflow,
        $border, $border, $page_size - $border, $page_size / 5,
        "fitmethod=auto");
    $p->delete_textflow($textflow);

    $p->end_page_ext("");
    
    $p->close_image($image);
    
    $p->end_document("");

    $buf = $p->get_buffer();
    $len = strlen($buf);
    
    header("Content-type: application/pdf");
    header("Content-Length: $len");
    header("Content-Disposition: inline; filename=softmask_effects.pdf");
    print $buf;
}
catch (PDFlibException $e) {
        echo ("PDFlib exception occurred:\n" . "[" . $e->get_errnum() . "] " .
                        $e->get_apiname() . ": " . $e->get_errmsg() . "\n");
        exit(1);
}
catch (Throwable $e) {
    echo ("PHP exception occurred: " . $e->getMessage() . "\n");
    exit(1);
}

$p = 0;

?>