[PHP/GD2] Transparante truecolor images

Pagina: 1
Acties:
  • 128 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

Topicstarter
Beste,

Driftig op zoek ben ik naar een manier om met de in PHP beschikbare GD2 functies een TrueColor plaatje te outputten met transparency (in het geval van de GD2 is PNG de meest voor de hand liggende optie).

In dit topic lukt het om een PNG-8 image met transparency te generen, een veredeld GIFje, waarbij een palet wordt gehanteerd. Het nadeel van dit palet is dat het maar 256 kleuren ondersteunt in tegenstelling tot de 2563 kleuren die in TrueColor (PNG-24) images beschikbaar zijn.

Dit topic suggereerd dat het helemaal niet mogelijk is met PNG-24. PhotoShop lukt het WEL! :?

Als je een imagecreatetruecolor() of imagecreatefrompng() maakt, wordt de achtergrond zwart. De enige manier die ik tot nu toe gevonden heb is het plaatje converteren naar een palet-based image, de achtergrond als transparant te zetten en te imagepng()-en. Het nadeel hiervan is dat als je een foto hebt waarbij
  1. het aantal kleuren gereduceerd wordt naar 256
  2. OVERAL de achtergrondkleur transparant wordt, ook op de plekken waar je dat niet wilt.
Weet iemand hoe hetzelfde mogelijk is, maar dan met behoud van alle kleuren?

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 00:12
Ik heb geen codevoorbeeld oid, maar bijna alle functies die op PHP staan met de term "alpha" in de naam gaan over het bewerken van PNG24 images met alpha-transparency. Afhankelijk van wat je wil lijkt het me wel mogelijk met behulp van imagealphablending(). Het tweede voorbeeld in de comments laat iig zien hoe je twee full-color images met alphakanalen kunt mergen zonder verlies van transparantie.

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Het gebruik van alpha channels is niet de transparantie die door Jurgle bedoeld wordt, vermoed ik. Internet Explorer kan namelijk niets met PNG's die alpha channels bevatten, echter, een transparante kleur is weer geen probleem.

Ik zal zometeen eens kijken of ik wat kan vinden. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

Topicstarter
Alpha blending is -inderdaad- niet wat ik zoek...

Als ik bijvoorbeeld een imagecreatetruecolor() doe en alle pixels stuk voor stuk op volledig transparent zet (met imagecolorallocatealpha($img, $r, $g, $b, 127)) heb ik nogsteeds een zwarte afbeelding.

Trouwens als je een truecolor PNG laadt en resize()-t, dan maakt hij van de transparent - ook zwarte pixels.

Als je de truecolor met transparency over een andere plakt, zonder te resizen, blijft de transparency inderdaad bewaard.

Plat gezegd is mijn doel een foto laden en 'een hap' eruit nemen en dat op de plek van de hap een transparante plek overblijft.

edit:
'-inderdaad-' toegevoegd in de eerste regel

@-NMe-: alvast bedankt

[ Voor 9% gewijzigd door Jurgle op 09-05-2005 19:03 ]

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Kun je niet met imagecolortransparent een transparante kleur uitkiezen, en daarna het vlak dat je transparant wil maken die kleur geven? Dat lijkt me het gewenste effect op te leveren? :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 00:12
-NMe- schreef op maandag 09 mei 2005 @ 19:21:
Kun je niet met imagecolortransparent een transparante kleur uitkiezen, en daarna het vlak dat je transparant wil maken die kleur geven? Dat lijkt me het gewenste effect op te leveren? :)
Bij mij op een windows-server met PHP4.3.0RC4 met GD werkte dat niet met truecolor images. Op een debian-doos met een (letterlijk) verse install van gd werkte het weer wel...

Welke versies van PHP en GD heeft TS eigenlijk?

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

Topicstarter
@T-MOB: PHP 5.0.3 en de Windows XP op mn laptop... het gaat op een Debian draaien met een WinXP als backup. GD versie is bundled (2.0.28 compatible).

@-NMe-: Dat werkt wel, maar als je dat doet met kleur X, wordt alles wat X is in de foto ook transparant :? Dat wil je natuurlijk niet. En een treucolor image transparant maken is me tot nu toe nog helemaal niet gelukt.

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Jurgle schreef op maandag 09 mei 2005 @ 22:08:
@-NMe-: Dat werkt wel, maar als je dat doet met kleur X, wordt alles wat X is in de foto ook transparant :? Dat wil je natuurlijk niet.
Toch is dat exact wat transparantie zonder alpha channel inhoudt. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • MadMan81
  • Registratie: April 2000
  • Laatst online: 31-08 22:46
De eerste kleur die alloceerd na het aanmaken van een image wordt toch de ondergrond kleur?
Zou dit dan niet werken:
PHP:
1
2
$im = imagecreatetruecolor($breedte, $hoogte);
$ondergrond_kleur = imagecolorallocatealpha ($im, 0, 0, 0, 127);

Cupra Born


Acties:
  • 0 Henk 'm!

  • jvdmeer
  • Registratie: April 2000
  • Laatst online: 00:16
Jurgle schreef op maandag 09 mei 2005 @ 22:08:
@T-MOB: PHP 5.0.3 en de Windows XP op mn laptop... het gaat op een Debian draaien met een WinXP als backup. GD versie is bundled (2.0.28 compatible).

@-NMe-: Dat werkt wel, maar als je dat doet met kleur X, wordt alles wat X is in de foto ook transparant :? Dat wil je natuurlijk niet. En een treucolor image transparant maken is me tot nu toe nog helemaal niet gelukt.
Toch een kwestie van de goede kleur kiezen om transparant te maken. er zijn 16777216 kleuren, en dat houdt in dat bij een foto van 4000*3000 pixels van ieder een unieke kleur nog steeds 4777216 kleuren beschikbaar zijn om transparant te maken.
Enige is om nu een kleur te kiezen die niet in de foto voorkomt. (zie daar je uitdaging...)

Acties:
  • 0 Henk 'm!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

Topicstarter
Hoe doet photoshop, of elk een beetje zichzelf respecterend grafisch programma, dat dan?
Denkbare oplossing (maar wel lelijk): Eerste zorgen dat in een afbeelding rgb(0,0,0) niet voorkomt (door bijv op rgb(1,0,0) te zetten) dan transparante kleur op rgb(0,0,0) te zetten en gummen maar?

Ik heb nog eens nader gekeken: transparant maken van een image in truecolor mode werkt niet, imagecolortransparent() werkt op mn laptop (winXP) alleen met pallete images, en dus een gereduceerd kleurenaantal (256).

EDIT: @jvdmeer: dat is waar en een unieke kleur vinden is geen probleem. Het probleem is iets transparent maken met GD2 en truecolor images.

[ Voor 13% gewijzigd door Jurgle op 09-05-2005 23:39 ]

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

MadMan81 schreef op maandag 09 mei 2005 @ 23:24:
De eerste kleur die alloceerd na het aanmaken van een image wordt toch de ondergrond kleur?
Zou dit dan niet werken:
PHP:
1
2
$im = imagecreatetruecolor($breedte, $hoogte);
$ondergrond_kleur = imagecolorallocatealpha ($im, 0, 0, 0, 127);
Dat is weer het alpha channel, wat nogmaals niet hetzelfde is als de bedoelde transparantie in dit topic. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

Topicstarter
Ik heb wel geprobeerd wat MadMan bedoelt, door de hele achtergrond te setPixel()-en naar een kleur met 127 als alpha waarde, maar dit resulteerde ook in een zwarte achtergrond.

edit:
dt-fout

[ Voor 7% gewijzigd door Jurgle op 09-05-2005 23:59 ]

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 00:12
MadMan81 schreef op maandag 09 mei 2005 @ 23:24:
De eerste kleur die alloceerd na het aanmaken van een image wordt toch de ondergrond kleur?
Zou dit dan niet werken:
Met een true-color image wordt de achtergrond altijd zwart. Flood-fillen met een alpha-channel resulteert er vervolgens in dat er over het zwart wordt geblend aan de hand van het alphakanaal. Met een transparantie van 127 blijft het dus gewoon zwart... helaas.
Jurgle schreef op maandag 09 mei 2005 @ 23:38:
Hoe doet photoshop, of elk een beetje zichzelf respecterend grafisch programma, dat dan?
Ik denk dat ze gewoon een kleur kiezen die niet wordt gebruikt. Een plaatje met alle mogelijke kleuren is zeer onwaarschijnlijk (wel leuk om een keer te testen trouwens, wat ie er mee zou doen).
Ik heb nog eens nader gekeken: transparant maken van een image in truecolor mode werkt niet, imagecolortransparent() werkt op mn laptop (winXP) alleen met pallete images, en dus een gereduceerd kleurenaantal (256).
Wat je zou kunnen proberen is om imagesavealpha() op false te zetten. Op mijn debian doos kan ik daarmee het wél of niet werken van transparantie togglen. De PHP-versie op mijn windowsbak ondersteunt die functie echter nog niet, maar je kunt het proberen.

Als workaround zou je nog kunnen overwegen om een belachelijk groot transparant plaatje te maken en die als achtergrond te gebruiken. Daar kun je dan de benodigde delen van het echte plaatje overheen plakken. Maargoed dat is in de categorie "als alle hoop verdwenen is" ;)

EDIT:
Onderstaande methoden zouden beide moeten werken gezien de GD en PHP versie:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
header("Content-type: image/png");
$img = imagecreatetruecolor(300,300);

/**
 * Method 1 */
imagealphablending($img, false); 

$trColor = imagecolorallocate($img, 255,0,0);
$trColor = imagecolortransparent($img, $trColor);
imagerectangle ($img, 100,100,200,200, $trColor);
imagefill($img, 101, 101, $trColor);

imagesavealpha($img, false);
imagepng($img);
/* end comment */


/**
 * Method 2 */
imagealphablending($img, false);

$trColor = imagecolorallocatealpha($img, 255,0,0,127);
imagerectangle ($img, 100,100,200,200, $trColor);
imagefill($img, 101, 101, $trColor);

imagesavealpha($img, true);
imagepng($img);
/* end comment*/
?>

[ Voor 21% gewijzigd door T-MOB op 10-05-2005 01:30 ]

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

Topicstarter
#Toegevoegd na onderstaande originele post: zie EDIT

YEHEW! Oplossing gevonden. T-Mob, je oplossing werkt, althans Method 1, Method 2 niet. Bij 1 moet de imagesavealpha() op TRUE worden gezet.

Alpha was in eerste instantie niet de oplossing, maar ik heb gegoogled en heb een manier gevonden om met IE het alpha-channel juist weer te geven:
Op http://user.fundy.net/morris/pngtest/pngtest.html staat een methode via CSS:
<div style="width: [WIDTH]px; height: [HEIGHT]px; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='[IMAGE_(EVT.RELATIEVE)_URL]');"></div>

Niet een mooie manier, maarja... IE zullen we maar zeggen. Met de link hierboven kun je ook een script vinden dat eerst ff checked of je IE of iets anders hebt, want deze code werkt vanzelfsprekend alleen met IE :'(

Ik vraag me af of dit een manier is waarbij je 2563 kleuren kunt gebruiken tegelijk met transparency. Het nadeel van de bovenstaande methode is trouwens dat je de hoogte en breedte moet weten van je plaatje (als dat dynamisch is weet je dat natuurlijk nog niet op het moment van HTML poepen).

Voor de geinteresseerden: deze link (http://www.google.nl/sear...y+internet+explorer&meta=) heb ik gebruikt om de html code te vinden. De tweede hit van deze zoekactie levert een leuke pagina op een MSDN blog op vol commentaar over de juiste implementatie van o.a. PNG en, het was nieuw voor mij, het bericht dat in februari dit jaar MSIE7.0 is aangekondigd waarover nog steeds geen officiele berichten bestaan omtrend PNG.

EDIT: Toch nog een addertje onder het gras: Bijvoorbeeld PhotoShop lukt het om TrueColor PNG's te generen, waarbij je NIET de speciale DIV methode hoeft toe te passen om transparency te bereiken. Dit is dus geen alpha kanaal! De zoektocht continueus hoe je dit voor elkaar krijgt met meer dan 256 kleuren...

[ Voor 13% gewijzigd door Jurgle op 10-05-2005 04:18 ]

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 00:12
Nu volg ik het niet helemaal meer. In bovenstaande code is method 1 de manier met truecolor images met 1 transparant kanaal. Zonder alphachannel dus. Dat werkt bij mij in IE en FF. De 2e methode gebruikt alpha-transparency, die zou dus niet moeten werken in IE.
Heb je het letterlijk gebprobeerd met mijn code?

Anyway misschien update ik vandaag de PHP versie op mijn windows bak nog. VInd het maar een vaag probleem...

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

Topicstarter
Method 1 levert in IE een zwart vierkant op met een rood vierkant erin, in FF is dit transparant.
Method 2 levert in beide een zwart vierkant op met een transparant vierkant erin.

Met de onderstaande html kun je via css toch een png in ie weergeven met alpha:
<div style="width: [WIDTH]px; height: [HEIGHT]px; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='[IMAGE_(EVT.RELATIEVE)_URL]');"></div>

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • jan-marten
  • Registratie: September 2000
  • Laatst online: 09-09 19:38
Ik weet niet of je er wat aan hebt maar ik kwam deze hier laatst ook tegen: Blendmodes. Dit gaat meer over blenden tussen twee plaatjes op verschillende manieren.
Pagina: 1