I have a directory of images in png format, which use a fixed color index for their encoding. I'm interested in producing images whose grayscale values correspond to the index itself, not the color for that index.
For example, suppose the color index has the entry index 3 -> (255, 0, 0) (red). I want to replace every instance of (255, 0, 0) in the RGB image with the grayscale value of 3.
My first thought is to 1) hard code the reversed color index into a lookup table 2) load the image, 3) iterate over pixels, doing a replace based on the look up table.
The problem with this is hard coding the lookup table. I can get it (via imagemagick identify), but that's tedious. Are there any libraries that can do this for me? I'm looking for either 1) cmd line transformations or 2) code libraries that get the color index for a pixel.
If you open a palettised image in PHP using GD, but accidentally forget to tell GD that it is palettised, you will actually get the palette index in the blue pixel. So you could take advantage of that to create a grayscale image by creating a truecolour image the same size as your original and then writing the palette index three times, once each for the Red, Green and Blue channels. It's easier than it sounds, here is the code:
#!/usr/local/bin/php
<?php
// Read in a palettised image
$im = imagecreatefrompng("pal.png");
// Create output image same size
$out = imagecreatetruecolor(imagesx($im), imagesy($im));
for ($x = 0; $x < imagesx($im); $x++) {
for ($y = 0; $y < imagesy($im); $y++) {
$pixel = imagecolorat($im, $x, $y);
$index = $pixel & 0xFF;
$outCol = imagecolorallocate($out,$index,$index,$index);
imagesetpixel($out,$x,$y,$outCol);
// printf("[%d,%d] Palette index:%d\n",$x,$y,$index);
}
}
imagepng($out,"result.png");
?>
So, if I create a 3 pixel palettised image with ImageMagick like this:
convert xc:red xc:lime xc:blue +append pal.png
and check it has palette like this
identify -verbose pal.png | more
Image: pal.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: PseudoClass
Geometry: 3x1+0+0
Units: Undefined
Type: Palette <--- it has a palette
Endianess: Undefined
Colorspace: sRGB
Depth: 8/1-bit
Channel depth:
red: 1-bit
green: 1-bit
blue: 1-bit
Channel statistics:
Pixels: 3
Red:
min: 0 (0)
max: 255 (1)
mean: 85 (0.333333)
standard deviation: 120.208 (0.471405)
kurtosis: -1.5
skewness: 0.707107
entropy: 0.918296
Green:
min: 0 (0)
max: 255 (1)
mean: 85 (0.333333)
standard deviation: 120.208 (0.471405)
kurtosis: -1.5
skewness: 0.707107
entropy: 0.918296
Blue:
min: 0 (0)
max: 255 (1)
mean: 85 (0.333333)
standard deviation: 120.208 (0.471405)
kurtosis: -1.5
skewness: 0.707107
entropy: 0.918296
Image statistics:
Overall:
min: 0 (0)
max: 255 (1)
mean: 85 (0.333333)
standard deviation: 120.208 (0.471405)
kurtosis: -1.5
skewness: 0.707107
entropy: 0.918296
Colors: 3
Histogram:
1: ( 0, 0,255) #0000FF blue
1: ( 0,255, 0) #00FF00 lime
1: (255, 0, 0) #FF0000 red
Colormap entries: 4
Colormap: <--- here is the palette
0: (255, 0, 0) #FF0000 red
1: ( 0,255, 0) #00FF00 lime
2: ( 0, 0,255) #0000FF blue
3: (255,255,255) #FFFFFF white
Then check the result.png after running the PHP script, it now looks like this - i.e. greyscale and the colours match the former indices.
identify -verbose result.png
Image: result.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: DirectClass
Geometry: 3x1+0+0
Units: Undefined
Type: Grayscale <--- it is now greyscale, no palette
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
gray: 8-bit
Channel statistics:
Pixels: 3
Gray:
min: 0 (0)
max: 2 (0.00784314)
mean: 1 (0.00392157)
standard deviation: 0.816497 (0.00320195)
kurtosis: -1.5
skewness: 0
entropy: 1
Colors: 3
Histogram:
1: ( 0, 0, 0) #000000 gray(0)
1: ( 1, 1, 1) #010101 gray(1)
1: ( 2, 2, 2) #020202 gray(2)
Note that if your original image had very few colour palette entries, the output image will be dark so you will want to contrast-stretch or normalize it...
Related
I'm trying to alter the displayed boot splash of an AMLogic device (using this tool: https://github.com/steeve/aml-imgpack). I have a JPG which I convert to BMP, as the device needs (let's say https://unsplash.com/photos/SnXIF8_2oPw) but the colors are completely wrong, the image is broken in "lines" and some parts from left are to the right (a bit like repeating the image, but not completely).
The original image, have the following attributes:
$ magick identify -verbose ../original/bootup.bmp
Image:
Filename: ../original/bootup.bmp
Format: BMP (Microsoft Windows bitmap image)
Class: DirectClass
Geometry: 1920x1080+0+0
Resolution: 28.34x28.34
Print size: 67.7488x38.1087
Units: PixelsPerCentimeter
Colorspace: sRGB
Type: TrueColor
Base type: Undefined
Endianness: Undefined
Depth: 8-bit
Channel depth:
Red: 8-bit
Green: 8-bit
Blue: 8-bit
Channel statistics:
Pixels: 2073600
Red:
min: 0 (0)
max: 255 (1)
mean: 4.64305 (0.018208)
standard deviation: 31.5717 (0.12381)
kurtosis: 47.4739
skewness: 6.93758
entropy: 0.0513943
Green:
min: 0 (0)
max: 255 (1)
mean: 3.77976 (0.0148226)
standard deviation: 26.4192 (0.103605)
kurtosis: 55.8096
skewness: 7.40689
entropy: 0.0502694
Blue:
min: 0 (0)
max: 239 (0.937255)
mean: 1.81429 (0.00711485)
standard deviation: 13.2764 (0.0520643)
kurtosis: 84.5432
skewness: 8.63456
entropy: 0.0528362
Image statistics:
Overall:
min: 0 (0)
max: 255 (1)
mean: 3.41236 (0.0133818)
standard deviation: 23.7558 (0.0931598)
kurtosis: 67.5353
skewness: 8.07788
entropy: 0.0515
Rendering intent: Perceptual
Chromaticity:
red primary: (0,0)
green primary: (0,0)
blue primary: (0,0)
white point: (0.3127,0.329)
Matte color: grey74
Background color: white
Border color: srgb(223,223,223)
Transparent color: none
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 1920x1080+0+0
Dispose: Undefined
Iterations: 0
Compression: Undefined
Orientation: Undefined
Convex hull: 931,391 932,391 1111,432 1223,484 1230,488 1247,544 1247,549 1244,551 1015,623 919,623 704,551 688,471 688,448 696,432 931,391
Minimum bounding box: 1247,391 1247,623 688,623 688,391
Properties:
date:create: 2020-10-31T22:40:38+00:00
date:modify: 2020-10-31T22:40:38+00:00
minimum-bounding-box:_p: 931,391
minimum-bounding-box:_q: 932,391
minimum-bounding-box:_v: 1015,623
minimum-bounding-box:angle: 0
minimum-bounding-box:area: 129688
minimum-bounding-box:height: 559
minimum-bounding-box:unrotate: -0
minimum-bounding-box:width: 232
signature: 31151e021e5d4cdde8d345165d8eb9cd6489f307272c8ca455d038002885d405
Artifacts:
verbose: true
Tainted: False
Filesize: 3.95515MiB
Number pixels: 2073600
Pixels per second: 79.4977MP
User time: 0.020u
Elapsed time: 0:01.026
Version: ImageMagick 7.0.10-30 Q16 x86_64 2020-09-20 https://imagemagick.org
I tried to convert using:
$ mogrify -format bmp ../new_bootup.jpg
$ mogrify -format bmp -type TrueColor ../new_bootup.jpg
$ mogrify -format bmp -define bmp:subtype=RGB565 ../new_bootup.jpg
but the image did not show correctly. The question is: which flags should I use (or which tool should I use) to achieve as close relpication of the original attributes as possible?
The jpeg image was decoded in a string saved in uploaded_io:
uploaded_io = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2....."
In rails 4 app, the image magick library has been installed and gem mini_magick is in Gemfile. From uploaded_io, we need to retrieve content_type, size and file name (no need to resize and manipulation of the image). We tried to use Ruby's base64 module in controller and there is no success (error and what decoded64 returns is not an image file):
require 'base64'
img = Base64.decode64(uploaded_io)
type = img.content_type #error
size = img.size #error
There is a similar post . But the ActiveSupport::Base64 is discontinued in Rails 4 and it can't be applied to Rails 4.
Not speaking Ruby or Rails, I don't really understand your question, but I think you are trying to get information about a base64-encoded image and I can maybe help with that. I am afraid I can only come towards you from the command-line side of things, but hopefully you can Ruby-ize that...
Let's create a little image:
convert -size 50x50 xc:red xc:lime xc:blue +append image.gif
To get information about an image with ImageMagick, you generally use the identify program from the IM suite, like this:
identify -verbose image.gif
Image: image.gif
Format: GIF (CompuServe graphics interchange format)
Mime type: image/gif
Class: PseudoClass
Geometry: 150x50+0+0
Units: Undefined
Type: Palette
Endianess: Undefined
Colorspace: sRGB
Depth: 8/1-bit
Channel depth:
red: 1-bit
green: 1-bit
blue: 1-bit
Channel statistics:
Pixels: 7500
Red:
min: 0 (0)
max: 255 (1)
mean: 85 (0.333333)
standard deviation: 120.208 (0.471405)
kurtosis: -1.5
skewness: 0.707107
entropy: 0.918296
Green:
min: 0 (0)
max: 255 (1)
mean: 85 (0.333333)
standard deviation: 120.208 (0.471405)
kurtosis: -1.5
skewness: 0.707107
entropy: 0.918296
Blue:
min: 0 (0)
max: 255 (1)
mean: 85 (0.333333)
standard deviation: 120.208 (0.471405)
kurtosis: -1.5
skewness: 0.707107
entropy: 0.918296
Image statistics:
Overall:
min: 0 (0)
max: 255 (1)
mean: 85 (0.333333)
standard deviation: 120.208 (0.471405)
kurtosis: -1.5
skewness: 0.707107
entropy: 0.918296
Colors: 3
Histogram:
2500: ( 0, 0,255) #0000FF blue
2500: ( 0,255, 0) #00FF00 lime
2500: (255, 0, 0) #FF0000 red
Colormap entries: 4
Colormap:
0: (255, 0, 0) #FF0000 red
1: ( 0,255, 0) #00FF00 lime
2: ( 0, 0,255) #0000FF blue
3: ( 0, 0, 0) #000000 black
Rendering intent: Perceptual
Gamma: 0.454545
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: red
Border color: srgb(223,223,223)
Matte color: grey74
Transparent color: black
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 150x50+0+0
Dispose: Undefined
Compression: LZW
Orientation: Undefined
Properties:
date:create: 2015-11-17T10:07:39+00:00
date:modify: 2015-11-17T10:07:39+00:00
signature: 48d1b973cce66f9a19f3b3738773a30f0519438d893cdfff2223e1941589e008
Artifacts:
filename: image.gif
verbose: true
Tainted: False
Filesize: 325B
Number pixels: 7.5K
Pixels per second: 7.5EB
User time: 0.000u
Elapsed time: 0:01.000
Version: ImageMagick 6.9.2-6 Q16 x86_64 2015-11-15 http://www.imagemagick.org
If I want to base64 encode that, I use openssl like this:
openssl enc -base64 -in image.gif
R0lGODlhlgAyAPEAAP8AAAD/AAAA/wAAACH5BAAAAAAALAAAAACWADIAAAL+hI+p
y50Bo5y02juF3rz7D4adQ5YmgqXqKonuC3PnTD/sjbfxzsv1f8oJb73iDogkDZcp
o9OVjC6Y1Mrz+pFqD9VuBAvebLdebzg81pa7Z3Bauq62se9onDq/1pN3Zv65h9S3
9OcUCDQ4VGh0+JMotFjUWPOYE9kzSVOJc8mTObNJ1BnzGRS6MkpaWnKKmvqyytra
9AoV6zBLWxtyi5t7sSvS2/ALHAwyzFBscYycrLBs1ezxDB2dMT1SjXKtky22zdX9
9Q0eDjBOXi5wbpAOsa7Rjv4ez97+HmA/n7+PXx+PH8B1AtP5O9cv4D+DChEOLFdw
3MFwCQkulNiQ4sMXbxG7TdxWEeJFjxlBbszW8drHaiG/FQAAOw==
The point of my post is to show that you can then pump that base64 mess into identify to interpret it, like this:
identify -verbose "data:image/gif;base64,R0lGODlhlgAyAPEAAP8AAAD/AAAA/wAAACH5BAAAAAAALAAAAACWADIAAAL+hI+p
> y50Bo5y02juF3rz7D4adQ5YmgqXqKonuC3PnTD/sjbfxzsv1f8oJb73iDogkDZcp
> o9OVjC6Y1Mrz+pFqD9VuBAvebLdebzg81pa7Z3Bauq62se9onDq/1pN3Zv65h9S3
> 9OcUCDQ4VGh0+JMotFjUWPOYE9kzSVOJc8mTObNJ1BnzGRS6MkpaWnKKmvqyytra
> 9AoV6zBLWxtyi5t7sSvS2/ALHAwyzFBscYycrLBs1ezxDB2dMT1SjXKtky22zdX9
> 9Q0eDjBOXi5wbpAOsa7Rjv4ez97+HmA/n7+PXx+PH8B1AtP5O9cv4D+DChEOLFdw
> 3MFwCQkulNiQ4sMXbxG7TdxWEeJFjxlBbszW8drHaiG/FQAAOw=="
Image:
Base filename: FQAAOw==
Format: GIF (CompuServe graphics interchange format)
Mime type: image/gif
Class: PseudoClass
Geometry: 150x50+0+0
Units: Undefined
Type: Palette
Endianess: Undefined
Colorspace: sRGB
Depth: 8/1-bit
Channel depth:
red: 1-bit
green: 1-bit
blue: 1-bit
Channel statistics:
Pixels: 7500
Red:
min: 0 (0)
max: 255 (1)
mean: 85 (0.333333)
standard deviation: 120.208 (0.471405)
kurtosis: -1.5
skewness: 0.707107
entropy: 0.918296
Green:
min: 0 (0)
max: 255 (1)
mean: 85 (0.333333)
standard deviation: 120.208 (0.471405)
kurtosis: -1.5
skewness: 0.707107
entropy: 0.918296
Blue:
min: 0 (0)
max: 255 (1)
mean: 85 (0.333333)
standard deviation: 120.208 (0.471405)
kurtosis: -1.5
skewness: 0.707107
entropy: 0.918296
Image statistics:
Overall:
min: 0 (0)
max: 255 (1)
mean: 85 (0.333333)
standard deviation: 120.208 (0.471405)
kurtosis: -1.5
skewness: 0.707107
entropy: 0.918296
Colors: 3
Histogram:
2500: ( 0, 0,255) #0000FF blue
2500: ( 0,255, 0) #00FF00 lime
2500: (255, 0, 0) #FF0000 red
Colormap entries: 4
Colormap:
0: (255, 0, 0) #FF0000 red
1: ( 0,255, 0) #00FF00 lime
2: ( 0, 0,255) #0000FF blue
3: ( 0, 0, 0) #000000 black
Rendering intent: Perceptual
Gamma: 0.454545
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: red
Border color: srgb(223,223,223)
Matte color: grey74
Transparent color: black
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 150x50+0+0
Dispose: Undefined
Compression: LZW
Orientation: Undefined
Properties:
date:create: 2015-11-17T10:12:05+00:00
date:modify: 2015-11-17T10:12:05+00:00
signature: 48d1b973cce66f9a19f3b3738773a30f0519438d893cdfff2223e1941589e008
Artifacts:
filename: data:image/gif;base64,R0lGODlhlgAyAPEAAP8AAAD/AAAA/wAAACH5BAAAAAAALAAAAACWADIAAAL+hI+p
y50Bo5y02juF3rz7D4adQ5YmgqXqKonuC3PnTD/sjbfxzsv1f8oJb73iDogkDZcp
o9OVjC6Y1Mrz+pFqD9VuBAvebLdebzg81pa7Z3Bauq62se9onDq/1pN3Zv65h9S3
9OcUCDQ4VGh0+JMotFjUWPOYE9kzSVOJc8mTObNJ1BnzGRS6MkpaWnKKmvqyytra
9AoV6zBLWxtyi5t7sSvS2/ALHAwyzFBscYycrLBs1ezxDB2dMT1SjXKtky22zdX9
9Q0eDjBOXi5wbpAOsa7Rjv4ez97+HmA/n7+PXx+PH8B1AtP5O9cv4D+DChEOLFdw
3MFwCQkulNiQ4sMXbxG7TdxWEeJFjxlBbszW8drHaiG/FQAAOw==
verbose: true
Tainted: False
Filesize: 325B
Number pixels: 7.5K
Pixels per second: 7.5EB
User time: 0.000u
Elapsed time: 0:01.000
Version: ImageMagick 6.9.2-6 Q16 x86_64 2015-11-15 http://www.imagemagick.org
[1]: http://i.stack.imgur.com/j9Ei0.gif
Or, you can use convert and re-create the image from its base64-encoded state like this:
{ echo "data:image/png;base64,"; openssl enc -base64 -in image.png; } | convert inline:- decoded.gif
I made a small image using imagemagick, this image has only 2 colors (alpha + some other color) so I want to turn in into index-color mode.
Once I finish the image, I run the command
convert file.png +dither -colors 2 file.png
The resulting image is 169 bytes. Now when I open the image with gimp, I make no change, I just export it as .png, over the old image, on the window that says "Export image as PNG" I untick everything, and keep compression level at 9.
The resulting image is 109 bytes. What makes this difference ? At first I thought it would be meta-data or something like that, I tried from imagemagick to use the -strip command, but it kept the image at 169 bytes. So, it it because of the compression algorithm? What compression algorithm does gimp use ? How can I replicate that with imagemagick?
The reason I want to do it with imagemagick is so I can automate the process, as I plan to do this on 100+ images.
EDIT:
Output of identify -verbose imagemagickfile.png
Image: ic_stage.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: DirectClass
Geometry: 176x176+0+0
Units: Undefined
Type: PaletteAlpha
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
red: 4-bit
green: 8-bit
blue: 1-bit
alpha: 1-bit
Channel statistics:
Pixels: 30976
Red:
min: 0 (0)
max: 102 (0.4)
mean: 60.0126 (0.235343)
standard deviation: 50.1973 (0.196852)
kurtosis: -1.87106
skewness: -0.359086
entropy: 0.977354
Green:
min: 0 (0)
max: 150 (0.588235)
mean: 88.2538 (0.346093)
standard deviation: 73.8196 (0.289489)
kurtosis: -1.87106
skewness: -0.359086
entropy: 0.977354
Blue:
min: 0 (0)
max: 255 (1)
mean: 150.031 (0.588359)
standard deviation: 125.493 (0.492131)
kurtosis: -1.87106
skewness: -0.359086
entropy: 0.977354
Alpha:
min: 0 (0)
max: 255 (1)
mean: 150.031 (0.588359)
standard deviation: 125.493 (0.492131)
kurtosis: -1.87106
skewness: 0.359086
entropy: 0.977354
Image statistics:
Overall:
min: 0 (0)
max: 255 (1)
mean: 100.817 (0.395359)
standard deviation: 99.3306 (0.389532)
kurtosis: -1.05614
skewness: 0.476254
entropy: 0.977354
Alpha: none #00000000
Colors: 2
Histogram:
12751: ( 0, 0, 0, 0) #00000000 none
18225: (102,150,255,255) #6696FFFF srgba(102,150,255,1)
Rendering intent: Perceptual
Gamma: 0.454545
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: srgba(255,255,255,1)
Border color: srgba(223,223,223,1)
Matte color: grey74
Transparent color: none
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 176x176+0+0
Dispose: Undefined
Iterations: 0
Compression: Zip
Orientation: Undefined
Properties:
date:create: 2015-10-26T11:27:21+02:00
date:modify: 2015-10-26T11:27:21+02:00
png:bKGD: chunk was found (see Background color, above)
png:cHRM: chunk was found (see Chromaticity, above)
png:IHDR.bit-depth-orig: 2
png:IHDR.bit_depth: 2
png:IHDR.color-type-orig: 3
png:IHDR.color_type: 3 (Indexed)
png:IHDR.interlace_method: 0 (Not interlaced)
png:IHDR.width,height: 176, 176
png:PLTE.number_colors: 3
png:sRGB: intent=0 (Perceptual Intent)
png:tRNS: chunk was found
signature: 219cc9a10e56ed2940dc1d92e37bec98d49d12c1bd5f2adfd2bcc91fd7b56f85
Artifacts:
filename: ic_stage.png
verbose: true
Tainted: False
Filesize: 218B
Number pixels: 31K
Pixels per second: 0B
User time: 0.000u
Elapsed time: 0:01.000
Version: ImageMagick 6.9.2-0 Q16 x86_64 2015-08-18 http://www.imagemagick.org
Output of identify -verbose gimpfile.png
Image: ic_stage_2.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: DirectClass
Geometry: 176x176+0+0
Units: Undefined
Type: PaletteAlpha
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
red: 4-bit
green: 8-bit
blue: 1-bit
alpha: 1-bit
Channel statistics:
Pixels: 30976
Red:
min: 102 (0.4)
max: 255 (1)
mean: 164.981 (0.646985)
standard deviation: 75.296 (0.295278)
kurtosis: -1.87106
skewness: 0.359086
entropy: 0.977354
Green:
min: 150 (0.588235)
max: 255 (1)
mean: 193.222 (0.757735)
standard deviation: 51.6737 (0.202642)
kurtosis: -1.87106
skewness: 0.359086
entropy: 0.977354
Blue:
min: 255 (1)
max: 255 (1)
mean: 255 (1)
standard deviation: 0 (0)
kurtosis: 0
skewness: 0
entropy: -nan
Alpha:
min: 0 (0)
max: 255 (1)
mean: 150.031 (0.588359)
standard deviation: 125.493 (0.492131)
kurtosis: -1.87106
skewness: 0.359086
entropy: 0.977354
Image statistics:
Overall:
min: 0 (0)
max: 255 (1)
mean: 179.543 (0.70409)
standard deviation: 77.6019 (0.304321)
kurtosis: 1.86389
skewness: -1.46287
entropy: -nan
Alpha: srgba(255,255,255,0) #FFFFFF00
Colors: 2
Histogram:
18225: (102,150,255,255) #6696FFFF srgba(102,150,255,1)
12751: (255,255,255, 0) #FFFFFF00 srgba(255,255,255,0)
Rendering intent: Perceptual
Gamma: 0.454545
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: white
Border color: srgba(223,223,223,1)
Matte color: grey74
Transparent color: none
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 176x176+0+0
Dispose: Undefined
Iterations: 0
Compression: Zip
Orientation: Undefined
Properties:
date:create: 2015-10-26T11:27:52+02:00
date:modify: 2015-10-26T11:27:52+02:00
png:IHDR.bit-depth-orig: 1
png:IHDR.bit_depth: 1
png:IHDR.color-type-orig: 3
png:IHDR.color_type: 3 (Indexed)
png:IHDR.interlace_method: 0 (Not interlaced)
png:IHDR.width,height: 176, 176
png:PLTE.number_colors: 2
png:sRGB: intent=0 (Perceptual Intent)
png:tRNS: chunk was found
signature: a22844c38c7ef3a612d94c2d3b9d1be29bb9d5e2f897f87c92947946fe6bc868
Artifacts:
filename: ic_stage_2.png
verbose: true
Tainted: False
Filesize: 138B
Number pixels: 31K
Pixels per second: 30.976GB
User time: 0.000u
Elapsed time: 0:01.000
Version: ImageMagick 6.9.2-0 Q16 x86_64 2015-08-18 http://www.imagemagick.org
I just found a piece of code that was used to determine if an image has transparent pixels:
my $alpha = $gd->transparent;
if ($alpha < 0) {
die("The image you uploaded has no transparent pixels. (alpha = $alpha)");
}
Obviously, this does not work. I tried it with the image user-desktop.png of the open icon library which has transparent pixels. The check returned -1.
I can only guess why this command was used. GD's manpage says:
If you call this method [transparent] without any parameters, it will return the current index of the transparent color, or -1 if none.
So, as a side question: the transparent pixels can have no color index at all - right?
Then I found the thread Perl GD check if pixel is transparent. But for this solution, I have to iterate over all pixels of an image (at least in the wort case, when the only transparent pixel would be the last one).
Isn't there an easy way of checking for this information? Maybe a method like $image_object->has_transparent_pixels ?
NB: I'm not bound to GD, so other Image modules might work as well (however, I'm on Windows - it should work there).
Updated Answer
As pointed out by #ikegami (thank you), GIFs have a designated transparent "colour" pixel in their palette rather than a alpha/transparency layer in which each pixel has its own transparency value, normally between 0-255.
I have generated a 2x2 pixel GIF with one transparent pixel, one red, one green and one blue - then ran ImageMagick's identify command against it and got the following. I have marked the transparent pixel parts with an arrow.
Image: a.gif
Format: GIF (CompuServe graphics interchange format)
Mime type: image/gif
Class: PseudoClass
Geometry: 4x4+0+0
Units: Undefined
Type: PaletteAlpha
Endianess: Undefined
Colorspace: sRGB
Depth: 8/1-bit
Channel depth:
red: 1-bit
green: 1-bit
blue: 1-bit
alpha: 1-bit
Channel statistics:
Pixels: 16
Red:
min: 0 (0)
max: 255 (1)
mean: 127.5 (0.5)
standard deviation: 127.5 (0.5)
kurtosis: -2
skewness: 0
Green:
min: 0 (0)
max: 255 (1)
mean: 127.5 (0.5)
standard deviation: 127.5 (0.5)
kurtosis: -2
skewness: 0
Blue:
min: 0 (0)
max: 255 (1)
mean: 127.5 (0.5)
standard deviation: 127.5 (0.5)
kurtosis: -2
skewness: 0
Alpha:
min: 0 (0)
max: 255 (1)
mean: 191.25 (0.75)
standard deviation: 110.418 (0.433013)
kurtosis: -0.666667
skewness: 1.1547
Image statistics:
Overall:
min: 0 (0)
max: 255 (1)
mean: 111.562 (0.4375)
standard deviation: 123.451 (0.484123)
kurtosis: -1.8275
skewness: 0.271109
Alpha: srgba(255,255,255,0) #FFFFFF00
Colors: 4
Histogram:
4: ( 0, 0,255,255) #0000FF blue
4: ( 0,255, 0,255) #00FF00 lime
4: (255, 0, 0,255) #FF0000 red
4: (255,255,255, 0) #FFFFFF00 srgba(255,255,255,0)
Colormap entries: 4
Colormap:
0: (255, 0, 0,255) #FF0000 red
1: ( 0,255, 0,255) #00FF00 lime
2: ( 0, 0,255,255) #0000FF blue
3: (255,255,255, 0) #FFFFFF00 srgba(255,255,255,0) <---------
Rendering intent: Perceptual
Gamma: 0.454545
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: srgba(255,255,255,0)
Border color: srgba(223,223,223,1)
Matte color: grey74
Transparent color: srgba(255,255,255,0) <---------------
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 4x4+0+0
Dispose: Undefined
Compression: LZW
Orientation: Undefined
Properties:
date:create: 2014-10-11T10:40:09+01:00
date:modify: 2014-10-11T10:40:08+01:00
signature: 1c82b4c2e772fb075994516cc5661e9dec35b8142f89c651253d07fc3c4642bb
Profiles:
Profile-gif:xmp dataxmp: 1031 bytes
Artifacts:
filename: a.gif
verbose: true
Tainted: False
Filesize: 1.11KB
Number pixels: 16
Pixels per second: 16PB
User time: 0.000u
Elapsed time: 0:01.000
Version: ImageMagick 6.8.9-7 Q16 x86_64 2014-09-10 http://www.imagemagick.org
So, IM does know about the GIF transparent pixel - I will dig some more and see if it can be found sensibly in Perl - for now though, you could just run the following in Perl's backticks.
my $output = `identify -verbose a.gif | grep -i transparent`; # or maybe with FINDSTR on Windows
As an alternatvie, and less problematic across platforms, the %A escape tells you if an image has transparency enabled:
convert a.gif -print "%A" null:
True
convert a.jpg -print "%A" null:
False
Or, in a more Perl-y way:
#!/usr/bin/perl
use warnings;
use strict;
use Image::Magick;
my $image = Image::Magick->new();
$image->Read($ARGV[0]);
my $a = $image->Get('%A');
print $a;
perl ./script.pl a.gif
True
perl ./script.pl a.jpg
False
Original Answer
I think you may be a little confused about transparency. Images either have transparency, which is an entire layer, or they do not. In general, it is not a question of a single pixel being transparent or not. From the outset, JPEGs do not support transparency, GIF and PNG can support transparency but they are not necessarily always transparent.
So, assuming you have a PNG or a GIF, it could have a transparency layer. If it has, each pixel could either be totally transparent, totally opaque or somewhere in between. If you use ImageMagick, it is available at the command line or with PHP, Perl and other bindings.
From the command line, you can tell if an image has a transparency layer using this command:
convert InputImage.png -format "%[opaque]" info:
and it will either return true or false.
In Perl you can do this:
#!/usr/bin/perl
use warnings;
use strict;
use Image::Magick;
my $image = Image::Magick->new();
$image->Read($ARGV[0]);
my $a = $image->Get('%[opaque]');
print $a;
then run as:
perl ./script.pl ImageName.png
I've been working on this Reddit puzzle:
http://www.reddit.com/r/playitforward/comments/1v6jfh/contest_first_one_to_solve_this_riddle_gets_my/
and most of users in the thread are stumped. Full disclosure, I'd love to win the prize, but by bringing attention to it and asking for assistance, I understand that I lessen my chances, but at this point I want to know what the image says more than anything.
We narrowed down the cyphers to a URL to a text file with PNG exif data, but when opened as a PNG, it turns out corrupted. Could this PNG be encrypted or purposely corrupted in a way to preserve the exif data and what would be the best way to unravel it? Note that the string of numbers and "AK" were explicitly linked to this clue, so I can only assume there is maybe an Asynchronous Key involved or some standard pioneered by Arjen Kampf Lenstra or some Angry Kid behind it all.
Sure, using ImageMagick like this:
# Look at rose image before we start, and its header
identify -verbose rose.jpg
Image: rose.jpg
Format: JPEG (Joint Photographic Experts Group JFIF format)
Mime type: image/jpeg
Class: DirectClass
Geometry: 70x46+0+0
Units: Undefined
Type: TrueColor
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
red: 8-bit
green: 8-bit
blue: 8-bit
Channel statistics:
Pixels: 3220
Red:
min: 31 (0.121569)
max: 255 (1)
mean: 145.56 (0.570825)
standard deviation: 69.1755 (0.271277)
kurtosis: -1.38839
skewness: 0.139004
entropy: 0.97057
Green:
min: 27 (0.105882)
max: 255 (1)
mean: 89.2475 (0.34999)
standard deviation: 52.4516 (0.205693)
kurtosis: 2.60505
skewness: 1.80798
entropy: 0.869705
Blue:
min: 21 (0.0823529)
max: 255 (1)
mean: 80.4214 (0.315378)
standard deviation: 54.9267 (0.215399)
kurtosis: 2.93861
skewness: 1.9566
entropy: 0.85334
Image statistics:
Overall:
min: 21 (0.0823529)
max: 255 (1)
mean: 105.076 (0.412064)
standard deviation: 59.3109 (0.232592)
kurtosis: 1.24657
skewness: 1.44732
entropy: 0.897872
Rendering intent: Perceptual
Gamma: 0.454545
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: white
Border color: srgb(223,223,223)
Matte color: grey74
Transparent color: black
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 70x46+0+0
Dispose: Undefined
Iterations: 0
Compression: JPEG
Quality: 92
Orientation: Undefined
Properties:
date:create: 2015-10-04T18:46:03+01:00
date:modify: 2015-10-04T18:46:03+01:00
jpeg:colorspace: 2
jpeg:sampling-factor: 1x1,1x1,1x1
signature: 38a8912b601557d5a377bff360f03804c383c3298b48d9917504b488e8f4152b
Artifacts:
filename: rose.jpg
verbose: true
Tainted: False
Filesize: 2.65KB
Number pixels: 3.22K
Pixels per second: 3.22EB
User time: 0.000u
Elapsed time: 0:01.000
Version: ImageMagick 6.9.1-10 Q32 x86_64 2015-10-02 http://www.imagemagick.org
Now add a comment into the image and encrypt it as encrypted.png:
convert -comment "Freddy frog" rose.jpg -encipher passphrase.txt encrypted.png
Check the header of encrypted image to see if EXIF data and comment and other data are visible within it - yes, they are:
identify -verbose encrypted.png
Image: encrypted.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: DirectClass
Geometry: 70x46+0+0
Units: Undefined
Type: TrueColor
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
red: 8-bit
green: 8-bit
blue: 8-bit
Channel statistics:
Pixels: 3220
Red:
min: 0 (0)
max: 255 (1)
mean: 126.755 (0.497077)
standard deviation: 73.7824 (0.289343)
kurtosis: -1.18047
skewness: 0.0142557
entropy: 0.99254
Green:
min: 0 (0)
max: 255 (1)
mean: 127.937 (0.501712)
standard deviation: 75.0501 (0.294314)
kurtosis: -1.23185
skewness: -0.0233363
entropy: 0.992485
Blue:
min: 0 (0)
max: 255 (1)
mean: 127.594 (0.500368)
standard deviation: 74.64 (0.292706)
kurtosis: -1.22352
skewness: -0.0177342
entropy: 0.992544
Image statistics:
Overall:
min: 0 (0)
max: 255 (1)
mean: 127.428 (0.499719)
standard deviation: 74.4927 (0.292128)
kurtosis: -1.21239
skewness: -0.00900116
entropy: 0.992523
Rendering intent: Perceptual
Gamma: 0.45455
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: white
Border color: srgb(223,223,223)
Matte color: grey74
Transparent color: black
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 70x46+0+0
Dispose: Undefined
Iterations: 0
Compression: Zip
Orientation: Undefined
Properties:
cipher:mode: CTR
cipher:nonce: d3d57ca43eacb27a9d72b65ef976923e5b761c7aaaee1d1914d1769ca4834488
cipher:type: AES
comment: Freddy frog <--- comment is visible
date:create: 2015-10-04T18:48:43+01:00
date:modify: 2015-10-04T18:48:43+01:00
png:bKGD: chunk was found (see Background color, above)
png:cHRM: chunk was found (see Chromaticity, above)
png:gAMA: gamma=0.45454544 (See Gamma, above)
png:IHDR.bit-depth-orig: 8
png:IHDR.bit_depth: 8
png:IHDR.color-type-orig: 2
png:IHDR.color_type: 2 (Truecolor)
png:IHDR.interlace_method: 0 (Not interlaced)
png:IHDR.width,height: 70, 46
png:sRGB: intent=0 (Perceptual Intent)
png:text: 6 tEXt/zTXt/iTXt chunks were found
signature: 273e3934027f6ffbcf00b3eca7eb0c576d8fd180e87133112ecacd59225986ee
Artifacts:
filename: encrypted.png
verbose: true
Tainted: False
Filesize: 10.1KB
Number pixels: 3.22K
Pixels per second: 3.22EB
User time: 0.000u
Elapsed time: 0:01.000
Version: ImageMagick 6.9.1-10 Q32 x86_64 2015-10-02 http://www.imagemagick.org
Now look at the encrypted image - junk
Decrypt image as decrypted.jpg - looks like a rose to me :-)
convert encrypted.png -decipher passphrase.txt decrypted.jpg