Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- define('ANONYMIZE_PNG',1);
- define('ANONYMIZE_JPG',ANONYMIZE_PNG+1);
- define('ANONYMIZE_GIF',ANONYMIZE_JPG+1);
- //Anonymizes an image by making all color channel values even.
- //It also removes color information from regions that are almost or completely transparent.
- //This defeats steganography in the least significant bits of color channels and steganography
- //that uses the color bytes of completely transparent pixels.
- //
- //Note: Will kill animation in gif files
- //
- //$data(string): Image data
- //$format(int=ANONYMIZE_PNG): Output a jpeg instead of PNG. Recommended if the source is jpeg
- //returns: Anonymized image data
- function anonymize_image($data,$format=ANONYMIZE_PNG){
- //Default to PNG if the programmer that calls this function is stupid (or a smartass)
- if(!in_array($format,array(ANONYMIZE_PNG,ANONYMIZE_JPG,ANONYMIZE_GIF))){
- $format=ANONYMIZE_PNG;
- }
- //Read as image
- $img=@imageCreateFromString($data);
- if(!$img){
- //bail if we failed to load
- return NULL;
- }
- //If we don't do this, PHP will read alpha values, but discards them when writing
- imageSaveAlpha($img,TRUE);
- $colors=imageColorsTotal($img);
- if($colors>0){
- //Palette based images are much easier to deal with.
- //We don't set the pixel values, we merely tweak the values in the palette
- //This doesn't makes sense with jpg, so we use GIF instead.
- if($format===ANONYMIZE_JPG){
- $format=ANONYMIZE_GIF;
- }
- for($i=0;$i<$colors;$i++){
- $col=imageColorsForIndex($img,$i);
- if($col['alpha']>0x70){
- //Make almost completely transparent regions fully transparent
- imageColorSet($img,$i,0xFF,0xFF,0xFF,0x7F);
- }
- elseif($col['alpha']<0x8){
- //Make almost completely opaque regions fully opaque
- imageColorSet($img,$i,$col['red']&0xFE,$col['green']&0xFE,$col['blue']&0xFE,0x00);
- }
- else{
- //Make colors even
- imageColorSet($img,$i,$col['red']&0xFE,$col['green']&0xFE,$col['blue']&0xFE,$col['alpha']&0xFE);
- }
- }
- }
- else{
- $w=imageSX($img);
- $h=imageSY($img);
- for($x=0;$x<$w;$x++){
- for($y=0;$y<$h;$y++){
- //Get color and make RGB even but don't touch alpha channel yet
- $c=imageColorAt($img,$x,$y)&0xFFFEFEFE;
- //Format of $c is 0xAARRGGBB
- //The alpha component can only range from 0x00 (opaque) to 0x7F (transparent) because this is PHP
- if($c>0xFFFFFF){
- //This pixel has alpha information.
- if(($c>>24)>=0x70){
- //Strip all color information from almost/completely transparent region
- $c=0x7FFFFFFF;
- }
- elseif(($c>>24)<=0x8){
- //Make fully opaque
- $c&=0x00FFFFFF;
- }
- }
- imageSetPixel($img,$x,$y,$c);
- }
- }
- }
- //Return new image data
- ob_start();
- switch($format){
- case ANONYMIZE_JPG:
- //75 is the default quality. Higher is better
- imageJpeg($img,NULL,90);
- break;
- case ANONYMIZE_GIF:
- //This has no options
- imageGif($img);
- break;
- default:
- //6 is the default compression. Higher is better
- imagePng($img,NULL,9);
- break;
- }
- imageDestroy($img);
- return ob_get_clean();
- }
- //Replace the file with one of your own for this demo
- $raw=file_get_contents('F:/test.png');
- $png=anonymize_image($raw,ANONYMIZE_PNG);
- $jpg=anonymize_image($raw,ANONYMIZE_JPG);
- $gif=anonymize_image($raw,ANONYMIZE_GIF);
- ?>
- <style>*{font-family:sans-serif;}img{border:2px solid #000;margin:0.5em;padding:0.5em;display:block;}</style>
- <p>PNG</p>
- <img src="data:image/png;base64,<?=base64_encode($png);?>" />
- <p>JPG</p>
- <img src="data:image/jpg;base64,<?=base64_encode($jpg);?>" />
- <p>GIF</p>
- <img src="data:image/gif;base64,<?=base64_encode($gif);?>" />
Add Comment
Please, Sign In to add comment