0

I'm trying to convert this java code to python:

BufferedImage image;
FileInputStream fstream1 = new FileInputStream("image.png")
image = ImageIO.read(fstream1);
int max = -40000000; //Java rgb returns negative values

for (int i = 0; i < 128; i++)
{
    for (int j = 0; j < 255; j++)
    {
        color = image.getRGB(j, i); //returns integer
.....

I tried this in python:

from PIL import Image

image = Image.open("image.png").convert("RGBA")
pixels = image.load()

for i in range(128):
    for j in range(255):
        color = pixels[j, i] #returns (R, G, B, A);

The problem however is that i'm getting different values in python.

Why does java returns negative integer values and how do i get the same result in python?

razz
  • 9,770
  • 7
  • 50
  • 68
  • Java returns an integer, in which the individual bytes represent the individual color channels (I don't know the exact order) – hlt Aug 18 '14 at 07:09
  • Why do you want negative values? – user253751 Aug 18 '14 at 07:10
  • sorry, thought u asked what do i mean.. i'm trying to convert the code to python so i need to get the same results – razz Aug 18 '14 at 07:13
  • Related: [_Get RGB of a BufferedImage_](http://stackoverflow.com/questions/10880083/get-rgb-of-a-bufferedimage) (explains why Java's `getRGB()` is returning negative values) – IQAndreas Aug 18 '14 at 07:23

2 Answers2

1

This function should convert a colour from the Python format to the Java format:

def convertPixel(c):
    x = c[0] << 16 | c[1] << 8 | c[2] | c[3] << 24
    if x >= 1<<31:
        x -= 1<<32
    return x

Note that Python's format is perfectly sane - it gives you the exact R, G, B and A values directly. It's Java that has the weird format.

You get negative values in Java because of integer overflow - for example 0xFFFFFFFF (or 4294967295), which is pure white, wraps around to -1.

user253751
  • 57,427
  • 7
  • 48
  • 90
  • it worked perfectly, thanks i could've never figured out myself this wierd formula :) – razz Aug 18 '14 at 07:45
  • just one question, does this value has any color property significance? like britness maybe or saturation! – razz Aug 18 '14 at 08:25
  • @razzak It's the R/G/B/A packed into a single integer. If you treat it as a single number, it's not very useful. Just about all you can do is move it around, and unpack it (back into R/G/B/A values) – user253751 Aug 18 '14 at 08:27
  • so a higher value or lower doesn't mean anything? – razz Aug 18 '14 at 08:27
  • @razzak Again, nothing useful. -16711681 is bright cyan, but -16711680 is the darkest shade of red (which will look black). – user253751 Aug 18 '14 at 08:29
1

The Java getRGB() value is a signed 32-bit integer with the alpha, R, G and B values in each of the 8 bits from most to least significant bytes.

You can 'reproduce' the same value with:

def packRGBA(r, g, b, a)
    val = a << 24 | r << 16 | g << 8 | b
    if a & 0x80:
        val -= 0x100000000
    return val

color = packRGBA(*pixels[j, i])
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343