Dynamic Range Compression

edited January 2017 in Questions about Code

My Code is not showing the image once i apply the dynamic range compression concept in it by using the formula S = greyLevel * log(1+r) help:)

    PImage image;
    PImage newImage;
    void setup(){
      image  = loadImage("frog.jpg");
      newImage= createImage(275,183,RGB);

    void draw(){
      for(int row = 0;row< width; row++)
         for(int column = 0;column< height;column++)
           //Dynamic range compression:
           int loc  = row +column * width;
           int pixelsValue  =  image.pixels[loc];

            newImage.pixels[loc] = int(255 * log(1 + pixelsValue));

            pixels[loc] = newImage.pixels[loc];



  • Answer ✓

    Format your code, edit post, select code and hit ctrl+o. Ensure there is an empty line above and below your code block.


  • You have very inefficient code there.

  • your rows are columns and your columns are rows.

    and you should add a noLoop() somewhere because you don't need to process the image more than once.

    but the big problem is that you are using the entire packed ARGB value of the pixel when your description says 'greyLevel'


  • koogs since it is 8bbp image so total grey level would be pow(2,8)-1 that is 255

  • if u run this code it won't show any image but once u get rid of the log from the f formula it then start showing the image . still don't know whats the problem

  • edited January 2017

    (um, adding println(pixelsValue) is a bad idea - too much println kills processing, so don't do that)

  • Answer ✓

    i've rewritten this, removing the unused stuff...

    it now prints the original in the top half of the screen, the modified version below.

    PImage img;
    void setup() {
      size(275, 366); // same width, twice the height
      img = loadImage("frog.jpg");
      println(img.width, img.height);
    void draw() {
      image(img, 0, 0);
      for (int i = 0 ; i < img.width * img.height ; i++) {
        int pixelsValue = img.pixels[i] & 0xff;
        int q = constrain(int(255 * log(1 + pixelsValue)), 0, 255);
        pixels[i + (img.width * img.height)] = 0xff000000 | (q << 16) | (q << 8) | q;
      // debug
      int p = img.pixels[0] & 0xff;
      int q = (int)(255 * log(1 + p));
      println(p, q);

    note the & 0xff in pixels value, this is getting the 0-255 greyscale value from the ARGB pixel. the q << 16 stuff is making an ARGB value from the modified log grey value.

    i still think that formula is a bit odd. for instance, an input of 148 returns 1276. i've tried constraining the value but you just end up with 255 everywhere, pure white.

  • in fact, anything other than a 0 or a 1 (totally black or very nearly totally black) gives a value outside 0-255

    0 0
    1 176
    2 280
    3 353
    4 410
    5 456
    6 496
    7 530
    8 560
    9 587
  • koogs yea it works thanks but i didn't get this line of code 0xff000000 | (q << 16) | (q << 8) | q i know we are performing left shift but why ? it is needed

  • edited January 2017

    "the q << 16 stuff is making an ARGB value from the modified log grey value."

    you have a grey value but you need a ARGB value. 8 bits per channel. alpha is always 0xff for fully opaque, then you need r, g and b all set to the grey value, which is what that's doing.


    this page has some background to dynamic range compression. suggests your 256 shouldn't be 256.


  • my results with the factor in line 16 set to 46 instead of 255


  • i got the point basically whatever value we are getting from the formula we are converting it into aarrggbb by shifting it by 16 , but y we are doing shifting by 8 . Sorry koogs i am asking a lot of question but i want to learn all this because i am liking this computer vision field . Sorry again

  • not quite.

    you have a grey scale value, 0-255, 8 bits gggggggg

    you need ARGB, which is, bitwise


    for grey the R, G and B are the same. for opaque the A is 0xff

    so that's

    11111111 gggggggg gggggggg gggggggg

    the << 16 moves the gggggggg to the RRRRRRRR

    the << 8 moves the gggggggg to the BBBBBBBB

    and |ing that all together gives you the ARGB needed for the pixel array.

  • there's a FAQ about this here:


    but the thing to remember is that for grey all the red, green and blue channels are the same.

  • edited January 2017

    You have here 4 bytes - A R G B.
    Now A should equal to 0xFF as it is fully opaque.
    R, G and B all should equal the value of the grey value (that's how grayscale works).
    So basically, you need this-

    • 0xFF for first byte.
    • Grey for second, third and fourth bytes.

    How? Grey will be of form 0x000000mn, where m and n are hexadecimal values.
    You need to make it into 0xffmnmnmn. (f is hexadecimal value for decimal 15 or binary 1111).
    So, you do a logical OR of 0xff000000 with 0x00mn0000, 0x0000mn00 and 0x000000mn. The latter three are nothing but grey shifted 16 and 8 spaces and grey itself.

  • (the non bit-shift way to fill a pixel in the above code would just be pixels[i] = color(q); but that's a lot slower - color() is more complicated than it looks)

  • (Yep, color is stupidly complicated. We had a similar discussion on color sometime back, but I'm unable to find it)

  • Thanks to u all I Finally understand this . Thanks for helping and thanks denial sir for suggesting me to join this forum . u all are fantastic

  • edited January 2017

    @Anupam --

    For a high-level overview of the paradigm (the RGB approach to defining grey vs the HSB approach to defining grey), you can also see the Processing Color tutorial and the discussion of color modes on the reference pages for basic processing commands.

  • it works for 24 bit depth images but once apply it for 8 bit depth image it dont work

  • We don't have up to date code or the image so we can't debug this for you...

  • edited January 2017

    But what you say is hard to believe given that processing converts both types to its internal pixel format on loading so there should be no difference.

Sign In or Register to comment.