Jump to content

Recommended Posts

I need some help in drawing an ellipse with fill and border, both having different alpha color

 

The code is,

 

<?php

$img = imageCreateTrueColor( 600, 600);

$red   = imagecolorallocatealpha($img, 255,   0,   0,50);
$blue  = imagecolorallocatealpha($img,   0,   0, 255,50);

imagefilledellipse  ($img, 300, 300, 400, 400, $red);
imagefilledellipse  ($img, 300, 300, 350, 350, $blue); 

header( 'Content-Type: image/png' );
imagePNG( $img );
imagedestroy($img);

?>

 

The image that I'm expecting is the test.png that I've attached with this post. But the output that I'm getting now is result.png (as attached)

 

Can anyone please help me with this.

 

Regards,

Hari

 

[attachment deleted by admin]

Link to comment
https://forums.phpfreaks.com/topic/193994-ellipse-with-border-and-fill-alpha/
Share on other sites

I need some help in drawing an ellipse with fill and border, both having different alpha color

 

The code is,

 

<?php

$img = imageCreateTrueColor( 600, 600);

$red   = imagecolorallocatealpha($img, 255,   0,   0,50);
$blue  = imagecolorallocatealpha($img,   0,   0, 255,50);

imagefilledellipse  ($img, 300, 300, 400, 400, $red);
imagefilledellipse  ($img, 300, 300, 350, 350, $blue); 

header( 'Content-Type: image/png' );
imagePNG( $img );
imagedestroy($img);

?>

 

The image that I'm expecting is the test.png that I've attached with this post. But the output that I'm getting now is result.png (as attached)

 

Can anyone please help me with this.

 

Regards,

Hari

 

What package is this? And can this produce pie charts and graphs and stuff?

You are going to have to play with your colors, not all blues are pure blue. And if you are going to really compare colors and expect exact representation to the eye you have to calibrate your monitor. For what you want try adding a bit of red and green to blue, 80,80,240 maybe.

 

 

HTH

Teamatomic

The function takes parameters for separate RGB values. So, this

$blue  = imagecolorallocatealpha($img,   0,   0, 255,50);

Red = 0, Green = 0, Blue = 255, could be expected to be the same as the HTML equivalent of #0000ff, which is close to the color in the test image.

 

But, that function also takes a fourth parameter (the alpha channel) for opacity! You are laying the blue image on top of the red image and the opacity is set at 50, which is somewhat transparent. So, some of the red from the first circle is bleeding through the blue.

 

Since I am assuming you want the blue to have the slightly subdued appearance as opposed to being completely opaque, my suggestioin would be that after you create the red circle and before you create the blue circle, you should create a completely opaque white circle (alpha set to 0) at the same size and position as you will be placing the blue circle. The blue circle will then be placed on top of a white background. If you get a funny looking edge around the blue circle try decreasing the size of the white circle slightly.

I just tested it and the blue came out perfectly (although my image defaulted to a black background which messes up the red. I suspect you are setting the initial background to white?). This code gives me the EXACT image you showed you were after above:

 

<?php
  
$img   = imageCreateTrueColor( 600, 600);
$red   = imagecolorallocatealpha($img, 255,   0,   0, 50);
$white = imagecolorallocatealpha($img, 255, 255, 255,  0);
$blue  = imagecolorallocatealpha($img,   0,   0, 255, 50);
  
imagefill ($img, 0, 0, $white);
imagefilledellipse  ($img, 300, 300, 400, 400, $red);
imagefilledellipse  ($img, 300, 300, 350, 350, $white);
imagefilledellipse  ($img, 300, 300, 350, 350, $blue);
  
header( 'Content-Type: image/png' );
imagePNG( $img );imagedestroy($img);
    
?>

Hi mjdamato,

 

Thanks for the help.

 

This worked... well sort of. I actually want the blue color to have an alpha too so that other shapes drawn below it can be visible. This is actually part of a much bigger project and this is the only thing which is missing. The ellipse can be drawn on top of other shapes/images and so if the blue color has an alpha then the background must also be visible. Any thoughts??

This is the code how I'm visualisizing the other shapes at the background.

 

<?php
  
$img   = imageCreateTrueColor( 600, 600);
$red   = imagecolorallocatealpha($img, 255,   0,   0, 50);
$white = imagecolorallocatealpha($img, 255, 255, 255,  0);
$blue  = imagecolorallocatealpha($img,   0,   0, 255, 50);
$green = imagecolorallocate($img,   0, 255,   0);
  
imagefill ($img, 0, 0, $white);

//Draw the background shape..a rectangle
imagefilledrectangle($img, 0,0,300,300, $green);

//Now draw the ellipse
imagefilledellipse  ($img, 300, 300, 400, 400, $red);
imagefilledellipse  ($img, 300, 300, 350, 350, $white);
imagefilledellipse  ($img, 300, 300, 350, 350, $blue);
  
header( 'Content-Type: image/png' );
imagePNG( $img );imagedestroy($img);
    
?>

Well, your original code was doing what it was supposed to do then - the red image was showing through the blue image. Although, I think I understand, what you are trying to accomplish. The only solution I can see is to do as one poster suggested above and modify the blue color (with the red showing through) to achieve the color you want.

 

EDIT: After a little trial and error I think you can get close to what you want by changing the Alpha value for the $white color. Try setting it to 50 and see what you think.

 

EDIT #2: Or you could look into using imagefilledarc() to create the red outer circle around the blue circle so it isn't underneath the blue circle.

Hi mjdamato,

 

I tried the imagefillearc to draw the outline image but the output was very very very bad.. Maybe I'm going wrong somewhere.

 

Here's the script

 

imagesetthickness($img, 20);
imagefilledarc  ( $img  , $centerx, $centery, $w, $h  , 0, 360  , $red  ,  IMG_ARC_NOFILL );

 

and the output is

 

[attachment deleted by admin]

Hi teamatomic,

 

That didn't work out.. I also thought that imagecolortransparent would set that particular color in the image to transparent and tried to set the imagecolortransparent($img,$white); in hopes that the white color that I drew second time (as per mjdamato's suggestion) would turn transparent. Didn't work either.

 

Hmm, I tried using imagecolortransparent() but with no positive results. BUt, I think I found a solution. When creating the blue circle we want it to have the set color with bleed-through for the green square but not the red circle.

 

So, using the same code as above, I created a completely opaque white circle so the blue circle would have the right color. But, since you want to have the green from the square show through - I created a 90 degree green arc on the white circle before placing the blue circle.

 

<?php
  
$img   = imageCreateTrueColor( 600, 600);
  
$white = imagecolorallocatealpha($img, 255, 255, 255,  0);
$green = imagecolorallocate($img, 0, 255, 0);
$red   = imagecolorallocatealpha($img, 255, 0, 0, 50);
$blue  = imagecolorallocatealpha($img, 0, 0, 255, 50);
  
imagefill ($img, 0, 0, $white);
  
//Draw the background shape..a rectangle
imagefilledrectangle($img, 0,0,300,300, $green);
  
//Now draw the objects
imagefilledellipse  ($img, 300, 300, 400, 400, $red);
imagefilledellipse  ($img, 300, 300, 350, 350, $white);
imagefilledarc($img, 300, 300, 350, 350, 180, 270, $green, IMG_ARC_PIE);
imagefilledellipse  ($img, 300, 300, 350, 350, $blue);
  
header( 'Content-Type: image/png' );
imagePNG( $img );imagedestroy($img);
    
?>

Hi mjdamato,

 

Thanks for the code. It works splendidly but the code assumes that the square will always be there. But my issue is that there could be any element anywhere (heck it could also be another ellipse at the back placed anywhere). For e.g

 

<?php
  
$img   = imageCreateTrueColor( 600, 600);
  
$white = imagecolorallocatealpha($img, 255, 255, 255,  0);
$green = imagecolorallocate($img, 0, 255, 0);
$red   = imagecolorallocatealpha($img, 255, 0, 0, 50);
$blue  = imagecolorallocatealpha($img, 0, 0, 255, 50);
  
imagefill ($img, 0, 0, $white);
  
//Draw the background shape..a rectangle
imagefilledrectangle($img, 20,100,500,500, $green);
  
//Now draw the objects
imagefilledellipse  ($img, 300, 300, 400, 400, $red);
imagefilledellipse  ($img, 300, 300, 350, 350, $white);
imagefilledarc($img, 300, 300, 350, 350, 180, 270, $green, IMG_ARC_PIE);
imagefilledellipse  ($img, 300, 300, 350, 350, $blue);
  
header( 'Content-Type: image/png' );
imagePNG( $img );imagedestroy($img);
    
?>

 

This time the image is not proper.

 

or is there a way of drawing an antialiased unfilled ellipse with a stroke and alpha color? This might also help me.

 

Regards,

Hari

I'm out of ideas then. I had already tried creating a solid color on top of the red circle and then setting it to transparent before placing the blue circle. That didn't work for me - it appears the transparency only applies to the specific color after the image is complete.

 

I also tried using imagesetthickness() and imageellipse() to just create a red outer ring. Looking at the descriptions and examples in the manual it shoudl work, but the output was always just a 1 pixel wide ring. Seems to be a bug as the manual states:

 

imagesetthickness() sets the thickness of the lines drawn when drawing rectangles, polygons, ellipses etc. etc. to thickness pixels

 

The only other option I can think of would be to create the red/blue circle as above (with a solid white circle in the middle) as a separate object and then merging that object on top of whatever other elements you need. Not really sure and don't intend to invest the time. Good luck to you.

I finally figured out how to do it and thought I might share with you too...

 

public function drawCircle($w,$h,$stroke,$scolor,$salpha,$fcolor){
	$multiplier = 2;
	$w=$w*$multiplier;
	$h=$h*$multiplier;
	$aw = (($w>$h)?($w)$h));
	$stroke*=$multiplier*2;

                $img = imageCreateTrueColor( $w,$h );
	imagealphablending($img,true);
	imageantialias($img, true);
	imagesavealpha($img, true);
	$color = imageColorAllocateAlpha( $img, 255, 255, 255, 127);
	imagefill( $img, 5, 5, $color );

	//Create the border
	imageellipse($img, ($w)/2, ($h)/2, $w, $h ,$scolor );
	imageellipse($img, ($w)/2, ($h)/2, $w-$stroke, $h-$stroke ,$scolor );

	imagefilltoborder($img, (($w)/2)-($w/2)+($stroke/4), (($h)/2), $scolor, $scolor);

	//Create the transparency for the border
	$trans = imageCreateTrueColor( $w,$h );
	imagealphablending($trans,true);
	imageantialias($trans, true);
	imagesavealpha($trans, true);
	$color = ImageColorAllocateAlpha( $trans, 255, 255, 255, 127);
	imagefill( $trans, 5, 5, $color );


	imagecopymerge_alpha($trans  , $img  , 0, 0, 0, 0, $w, $h , $salpha);
	imagedestroy($img);
	$img = $trans;

	//Draw the fill color
	//$blue  = imagecolorallocatealpha($img,   0,   0, 255,100);
	imagefilledellipse  ($img,($w)/2, ($h)/2,$w-$stroke, $h-$stroke,$fcolor);

	$resizedimage = imagecreatetruecolor(($w)/$multiplier, $h/$multiplier);
	imagealphablending($resizedimage,true);
	imageantialias($resizedimage, true);
	imagesavealpha($resizedimage, true);
	$color = imageColorAllocateAlpha( $resizedimage, 255, 255, 255, 127);
	imagefill( $resizedimage, 5, 5, $color );

	imagecopyresampled($resizedimage , $img, 0, 0, 0, 0, ($w)/$multiplier, ($h)/$multiplier, ($w), ($h));

	imagedestroy($img);
	return $resizedimage;
}

 

Hope this helps someone :)

Forgot to post the other method used ...

 

 

private function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
    if(!isset($pct)){
	return false;
    }
    //$pct /= 100;
    // Get image width and height
    $w = imagesx( $src_im );
    $h = imagesy( $src_im );
    // Turn alpha blending off
    imagealphablending( $src_im, false );
    // Find the most opaque pixel in the image (the one with the smallest alpha value)
    $minalpha = 127;
    for( $x = 0; $x < $w; $x++ )
    for( $y = 0; $y < $h; $y++ ){
	$alpha = ( imagecolorat( $src_im, $x, $y ) >> 24 ) & 0xFF;
	if( $alpha < $minalpha ){
	    $minalpha = $alpha;
	}
    }
    //loop through image pixels and modify alpha for each
    for( $x = 0; $x < $w; $x++ ){
	for( $y = 0; $y < $h; $y++ ){
	    //get current alpha value (represents the TANSPARENCY!)
	    $colorxy = imagecolorat( $src_im, $x, $y );
	    $alpha = ( $colorxy >> 24 ) & 0xFF;
	    //calculate new alpha
	    if( $minalpha !== 127 ){
		$alpha = 127 + 127 * $pct * ( $alpha - 127 ) / ( 127 - $minalpha );
	    } else {
		$alpha += 127 * $pct;
	    }
	    //get the color index with new alpha
	    $alphacolorxy = imagecolorallocatealpha( $src_im, ( $colorxy >> 16 ) & 0xFF, ( $colorxy >> 8 ) & 0xFF, $colorxy & 0xFF, $alpha );
	    //set pixel with the new color + opacity
	    if( !imagesetpixel( $src_im, $x, $y, $alphacolorxy ) ){
		return false;
	    }
	}
    }
    // The image copy
    imagecopy($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
    
}

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.