PDFlib Cookbook

cookbook

color/blendmode updated

Demonstrate all blend modes available in PDF.

Download PHP Code  Switch to Java Code  Show Output 

<?php
/*
 * Blend modes:
 * Demonstrate all blend modes which are available in PDF
 *
 * The following layers are used for demonstration:
 * - an RGB image
 * - SVG logo (with white background) and a black and white gradient
 *
 * Each blend mode is demonstrated twice, once with the image as background
 * and once with the image as foreground.
 *
 * Required software: PDFlib/PDFlib+PDI/PPS 10
 *
 * Required data: image, SVG graphics
 */

define('WIDTH', 170);
define('HEIGHT', 170);

function place_image($p, $image) {
    /* Place image */
    $p->fit_image($image, 0, 0, 
                    "boxsize={" . WIDTH . " " . HEIGHT . "} " .
                                     "fitmethod=slice position={0 0}");
}

function paint($p, $shp, $graphics) {
    /* Place SVG graphics over top half of the image */
    $p->fit_graphics($graphics, 0.2 * WIDTH, 0.6 * HEIGHT,
        "boxsize={ " . (0.6 * WIDTH) . " " . (0.3 * HEIGHT) .
        "} position={center} fitmethod=meet");

    /* Paint shading pattern over lower half of image */
    $p->set_graphics_option("fillcolor={pattern " . $shp . "}");
    
    $p->rect(0, 0, WIDTH, HEIGHT / 2);
    $p->fill();
}

/*
 * Create a template which demonstrates a particular blend mode
 */
function create_blendmode_sample($p, $blendmode, $image_in_background, $shp, 
                $image, $graphics) {

    $gs = $p->create_gstate("blendmode=" . $blendmode);
    
    $templ = $p->begin_template_ext(WIDTH, HEIGHT, "");
    
    if ($image_in_background) {
        place_image($p, $image);
        $p->set_gstate($gs); /* Set gstate with selected blend mode */
        paint($p, $shp, $graphics);
    } else {
        paint($p, $shp, $graphics);
        $p->set_gstate($gs); /* Set gstate with selected blend mode */
        place_image($p, $image);
    }
    
    $p->end_template_ext(0, 0);
    
    return $templ;
}
class blendmoderecord {
    function __construct($name, $notes) {
        $this->name = $name;
        $this->notes = $notes;
    }
}

/* This is where the data files are. Adjust as necessary. */
$searchpath = dirname(__FILE__,3) . "/input";
$graphicsFileName = "PDFlib-blue-logo-white-background.svg";
$imageFileName = "Lucy.jpg";
$title = "Blend mode";

/* Borders for the table fitbox */
$border = 30;

/* Records with all blend modes */
$blendmodes = array (
    new blendmoderecord("Normal", 
            "no blending effect: foreground obscures background"),
    new blendmoderecord("Darken", "symmetric mode"),
    new blendmoderecord("Multiply", "symmetric mode"),
    new blendmoderecord("ColorBurn", ""),
    new blendmoderecord("Lighten", "symmetric mode"),
    new blendmoderecord("Screen", "symmetric mode"),
    new blendmoderecord("ColorDodge", ""),
    new blendmoderecord("HardLight", ""),
    new blendmoderecord("SoftLight", ""),
    new blendmoderecord("Overlay", ""),
    new blendmoderecord("Difference", "symmetric mode"),
    new blendmoderecord("Exclusion", "symmetric mode"),
    new blendmoderecord("Hue", ""),
    new blendmoderecord("Saturation", ""),
    new blendmoderecord("Color", ""),
    new blendmoderecord("Luminosity", 
            "Like \"Color\", but with foreground and background exchanged") 
);

try {
    $p = new pdflib();
    $tf = 0;
    $tbl = 0;
    
    $pagewidth = 595;
    $pageheight = 842;
    $margin = 6;
    $rowheight = 180;
    $fontsize = 11;
    
    $p->set_option("searchpath={" . $searchpath . "}");
    
    /* This means that errors throw an exception */
    $p->set_option("errorpolicy=exception");
    
    
    if ($p->begin_document("", "") == 0)
        throw new Exception("Error: " . $p->get_errmsg());
    
    $p->set_info("Creator", "PDFlib Cookbook");
    $p->set_info("Title", $title);
    
    $tf_optlist = "fontname=NotoSerif-Regular fontsize=" . $fontsize;
    
    /* Set some general text options shared among all cells */
    $textoptlist = "fittextline={" . $tf_optlist .
                     " position={left center}} margin=" . $margin . " ";
    
    /* Load image */
    $image = $p->load_image("auto", $imageFileName, "");
    
    /* Load the SVG graphics */
    $graphics = $p->load_graphics("auto", $graphicsFileName, "");
    
    /* Create axial shading */
    $sh = $p->shading("axial", 0, HEIGHT / 2, WIDTH, HEIGHT / 2, 0, 0, 0, 0, 
                    "startcolor=black endcolor=white");
    
    /* shading pattern handle */
    $shp = $p->shading_pattern($sh, "");
    
    /*
     * ----------------------------------
     * Create table header for all cells
     * ----------------------------------
     */
    
    $row = 1;
    $cellopts = $textoptlist;
    $tbl = $p->add_table_cell($tbl, 1, $row, "Blend mode", $cellopts);
    
    $cellopts = $textoptlist;
    $tbl = $p->add_table_cell($tbl, 2, $row, "Notes", $cellopts);
    
    $tf = $p->add_textflow(0, 
                    "Image in background,\nlogo and shading in foreground", 
                    $tf_optlist . " lastalignment=center alignment=center");
    
    $cellopts = $textoptlist . " textflow=" . $tf;
    $tbl = $p->add_table_cell($tbl, 3, $row, "", $cellopts);
    
    $tf = $p->add_textflow(0, 
                    "Logo and shading in background,\nimage in foreground", 
                    $tf_optlist . " lastalignment=center alignment=center");
    
    $cellopts = $textoptlist . " textflow=" . $tf;
    $tbl = $p->add_table_cell($tbl, 4, $row, "", $cellopts);
    
    /*
     * ------------------------------------------------
     * Add a row for each blend mode
     * ------------------------------------------------
     */
    for($i = 0, $row = 2; $i < count($blendmodes); $i++, $row++) {
        /*
         * -------------------------------------------------------------
         * Column 1: Blend mode name
         * -------------------------------------------------------------
         */
        $cellopts = "colwidth=15% " . $textoptlist;
        
        $tbl = $p->add_table_cell($tbl, 1, $row, $blendmodes[$i]->name, 
                        $cellopts);
        
        /*
         * ---------------------------------------------
         * Column 2: Notes
         * ---------------------------------------------
         */
        
        $tf = $p->add_textflow(0, $blendmodes[$i]->notes, $tf_optlist);
        
        $cellopts = "colwidth=20% " . $textoptlist . " textflow=" . $tf;
        $tbl = $p->add_table_cell($tbl, 2, $row, "", $cellopts);
        
        /*
         * -------------------------------------------------------------
         * Column 3: image in background
         * -------------------------------------------------------------
         */
        $templ = create_blendmode_sample($p, $blendmodes[$i]->name, TRUE, $shp, 
                        $image, $graphics);
        
        $cellopts = "rowheight=" . $rowheight . " margin=3 image=" . $templ;
        
        $tbl = $p->add_table_cell($tbl, 3, $row, "", $cellopts);
        
        /*
         * -------------------------------------------------------------
         * Column 4: image in foreground
         * -------------------------------------------------------------
         */
        $templ = create_blendmode_sample($p, $blendmodes[$i]->name, FALSE, 
                        $shp, $image, $graphics);
        
        $cellopts = "rowheight=" . $rowheight . " margin=3 image=" . $templ;
        
        $tbl = $p->add_table_cell($tbl, 4, $row, "", $cellopts);
    } /* for */
    
    /*
     * -----------------------------------------------------------------
     * Fit the table. Using "header=1" the table header will include the
     * first line. Using "line=horother linewidth=0.3" the ruling is
     * specified with a line width of 0.3 for all horizontal lines.
     * -----------------------------------------------------------------
     */
    $tableoptlist = "showgrid header=1 stroke={ {line=horother linewidth=0.3}}";
    
    do {
        $p->begin_page_ext($pagewidth, $pageheight, "");
        
        /* Place the table instance */
        $result = $p->fit_table($tbl, $border, $border, $pagewidth - $border, 
                        $pageheight - $border, $tableoptlist);
        if ($result == "_error")
            throw new Exception("Couldn't place table : " . $p->get_errmsg());
        
        $p->end_page_ext("");
    } while ( $result == "_boxfull" );
    
    /* Check the result; "_stop" means all is ok. */
    if ($result != "_stop") {
        if ($result == "_error") {
            throw new Exception("Error when placing table: " . $p->get_errmsg());
        }
    }
    
    /* This will also delete Textflow handles used in the table */
    $p->delete_table($tbl, "");
    
    $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=blendmode.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;
?>