Note that there are some explanatory texts on larger screens.

plurals
  1. POAlgorithm to scale a raw 24 bit pixelmap to greater than 50% in C
    primarykey
    data
    text
    <p>Reducing a raw pixelmap to a value of 50% is easy. I simply slide a 2x2 square across the map and average the RGB components of the 4 pixels as follows:</p> <pre><code> img = XGetImage(d_remote,RootWindow(d_remote,0),0,0,attr.width,attr.height,XAllPlanes(),ZPixmap); int i; int j; for(i=0;i&lt;attr.height;i=i+2){ for(j=0;j&lt;attr.width;j=j+2) { unsigned long p1 = XGetPixel(img, j, i); unsigned long p1R = p1 &amp; 0x00ff0000; unsigned long p1G = p1 &amp; 0x0000ff00; unsigned long p1B = p1 &amp; 0x000000ff; unsigned long p2 = XGetPixel(img, j+1, i); unsigned long p2R = p2 &amp; 0x00ff0000; unsigned long p2G = p2 &amp; 0x0000ff00; unsigned long p2B = p2 &amp; 0x000000ff; unsigned long p3 = XGetPixel(img, j, i+1); unsigned long p3R = p3 &amp; 0x00ff0000; unsigned long p3G = p3 &amp; 0x0000ff00; unsigned long p3B = p3 &amp; 0x000000ff; unsigned long p4 = XGetPixel(img, j+1, i+1); unsigned long p4R = p4 &amp; 0x00ff0000; unsigned long p4G = p4 &amp; 0x0000ff00; unsigned long p4B = p4 &amp; 0x000000ff; unsigned long averageR = (p1R+p2R+p3R+p4R)/4 &amp; 0x00ff0000; unsigned long averageG = (p1G+p2G+p3G+p4G)/4 &amp; 0x0000ff00; unsigned long averageB = (p1B+p2B+p3B+p4B)/4 &amp; 0x000000ff; int average = averageR | averageG | averageB; XPutPixel(newImg, j/2, i/2, average); } } </code></pre> <p>This would make a pixelmap that is 500x500 turn into one that is 250x250. This is a 50% reduction. What if I wanted to scale it by 20%. For example I would like my 500x500 image to turn into 400x400? The smallest square I can slide is a 2x2. I don't see how I can get a reduction that is not a perfect power of 2.</p> <h1>Solution:</h1> <p>How's this for effort?? I modified a script I found that does bi-linear interpolation to work on XImages. It should work for any generic pixelmap. I do find the code ugly though since I see images as 2d arrays. I don't see why all the image code is mapped to a 1d array. It's harder to visualize. This works for any resize.</p> <pre><code>void resize(XImage* input, XImage* output, int sourceWidth, int sourceHeight, int targetWidth, int targetHeight) { int a, b, c, d, x, y, index; float x_ratio = ((float)(sourceWidth - 1)) / targetWidth; float y_ratio = ((float)(sourceHeight - 1)) / targetHeight; float x_diff, y_diff, blue, red, green ; int offset = 0 ; int i=0; int j=0; int* inputData = (int*)input-&gt;data; int* outputData = (int*)output-&gt;data; for (i = 0; i &lt; targetHeight; i++) { for (j = 0; j &lt; targetWidth; j++) { x = (int)(x_ratio * j) ; y = (int)(y_ratio * i) ; x_diff = (x_ratio * j) - x ; y_diff = (y_ratio * i) - y ; index = (y * sourceWidth + x) ; a = inputData[index] ; b = inputData[index + 1] ; c = inputData[index + sourceWidth] ; d = inputData[index + sourceWidth + 1] ; // blue element blue = (a&amp;0xff)*(1-x_diff)*(1-y_diff) + (b&amp;0xff)*(x_diff)*(1-y_diff) + (c&amp;0xff)*(y_diff)*(1-x_diff) + (d&amp;0xff)*(x_diff*y_diff); // green element green = ((a&gt;&gt;8)&amp;0xff)*(1-x_diff)*(1-y_diff) + ((b&gt;&gt;8)&amp;0xff)*(x_diff)*(1-y_diff) + ((c&gt;&gt;8)&amp;0xff)*(y_diff)*(1-x_diff) + ((d&gt;&gt;8)&amp;0xff)*(x_diff*y_diff); // red element red = ((a&gt;&gt;16)&amp;0xff)*(1-x_diff)*(1-y_diff) + ((b&gt;&gt;16)&amp;0xff)*(x_diff)*(1-y_diff) + ((c&gt;&gt;16)&amp;0xff)*(y_diff)*(1-x_diff) + ((d&gt;&gt;16)&amp;0xff)*(x_diff*y_diff); outputData[offset++] = (int)red &lt;&lt; 16 | (int)green &lt;&lt; 8 | (int)blue; } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload