Jump to content

[SOLVED] Combining images with a multiply or linear burn effect


phpknight

Recommended Posts

I have two PNG images that I need to resize and place on top of one another while preserving transparency.  I have accomplished this successfully.

 

However, I realized that I actually need to place the top image on top of the bottom one by applying what in graphics programs would be a linear burn or a multiply.  I am not sure which one to use yet, but here is the question:

 

1.) Is there a way to do with with PHP GD functions?  I am 95% sure it is not.  So, this leads to the second question.

2.) What sort of mathematical operation would I have to apply to the RGB values on a pixel by pixel basis to get the desired effect?  And is it something you do to the R, G, and B values separately or the color as a whole?

 

Thanks!

For anybody thinking of helping, here is some more information.

 

I figured out it is all done RGB and alpha stuff.  I do not know the equation yet, but I know what I need from the pixel information: a function similar to imagecolorat() but which retains the alpha information as well.  I see where you can do imagecolorexact, etc., but that is the reverse of what I need.  Plus I am working with true color images, so the palette, so the index stuff is not very helpful.  For a few of them, it says you can bit shift back to the RGB, so I am assuming a similar bitshift would work for alpha channel.  Then, I have to apply some equation to the colors and get a new one.

are you trying to vary the transparency of the 2nd image

 

<?php
$im1 = imagecreatefromjpeg('image1.jpg');
$im2 = imagecreatefromjpeg('image2.jpg');

$h = imagesy($im2);
$w = imagesx($im2);

$step = 100/$h;

for ($i=0; $i < $h; $i++)
{
    /**
    * copymerge image2 1 row of pixels ar a time
    * varying transparency with each row
    */
    imagecopymerge($im1, $im2, 0,$i, 0, $i, $w, 1, $i*$step);
}

header ("content-type:image/jpeg");
imagejpeg($im1);
imagedestroy($im1);
imagedestroy($im2);
?> 

Barand,

 

Thanks for the reply.  Since you are the image expert, I am really dead if I cannot get this working now, lol! I am trying to take every pixel and do what would be a multiply or linear burn in photoshop.  So, if I put a off white and red block on a light blue background, it would show up as a maroonish color, but the off white would almost be identical to the blue--just a little off.

 

I noticed PHP has some layer/image effects, but it is only overlay.  It does not appear to do either of these.

 

Even if I would be able to take two images and know the RGB and ALPHA values for the pixels (using a true color PNG), I should be able to find some equation to do the blend and then put the third pixel on a new image.  So, that is a workaround.

 

Any idea where to go next?

I saw an example somewhere that I thought might be useful. 

 

  $pixelrgb = imagecolorat($im,$x,$y);

  $cols = imagecolorsforindex($im, $pixelrgb);

 

I did a test with a var_dump on $cols.  The alpha channel is there.  I am pretty sure the alpha values would always be either zero or 127 for what I am doing.  So, I can get the RGB-alpha values for each image and do an equation to get the pixel for the new value.

 

Now, I just need to figure out how to do a linear burn and/or multiply from mathematical standpoint.  Any ideas?  Also, if you think there might be a faster way to do this than pixel by pixel, let me know.

is this any help

 

<?php
$col1 = 'FF0000';                      // colours to be averaged
$col2 = '0000FF';

$avg =  average_color ($col1, $col2);

echo "<table width='300'>
        <tr>
        <td>Color 1</td>
        <td>Average</td>
        <td>Color 1</td>
        </tr>
        <tr>
        <td style='background-color: #$col1'><span style='color: black'>$col1</span><br><span style='color: white'>$col1</span></td>
        <td style='background-color: #$avg'><span style='color: black'>$avg</span><br><span style='color: white'>$avg</span></td>
        <td style='background-color: #$col2'><span style='color: black'>$col2</span><br><span style='color: white'>$col2</span></td>
        </tr>
        </table>";

function rgb($hex)
{
    $c = hexdec($hex);
    $r = ($c >> 16) & 0xFF;
    $g = ($c >>  & 0xFF;
    $b = $c & 0xFF;
    return array($r,$g,$b);
}

function average_color ($col1, $col2)
{
    $rgb1 = rgb($col1);
    $rgb2 = rgb($col2);

    $avg = array();
    for ($i=0; $i<3; $i++)
    {
        $avg[$i] = floor(($rgb1[$i] + $rgb2[$i])/2);
    }
    
    $c = ($avg[0] << 16) + ($avg[1] <<  + $avg[2];
    
    return dechex($c);
}

?>

Calculates averages of the rgb components

 

[pre]

              R        G        B

Col 1        FF        00      00

Col 2        00        00      FF

            -----------------------

Avg          7F        00      7F

Barand,

 

No, I don't think that would work because with linear burn and multiply anything combined with black is just black.  So, mixing anything with 0, 0, 0, is black.  It is not a simple average. 

 

I am not sure this page has the answer, but this it has some good explanations.  I am not sure what absolute color values are,though.

http://www.simpelfilter.de/en/grundlagen/mixmods.html

 

Also, page two of this page has a description of multiply and linear burn.  Don't worry about the multiple stokes thing, I am just doing this once.

http://www.entomology.umn.edu/museum/links/coursefiles/ENT%205051/PDF%20documents/Blend%20Modes.pdf.  You should probably look at this one first.

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.