简体   繁体   中英

what does “ int pix = (0xff & ((int) first[ij])); ” mean?

The following code is part of a working camera app that detects motion and saves preview, painting the moving parts red.

public class RgbMotionDetection implements IMotionDetection {
that detects motion       
private static final int mPixelThreshold = 50; // Difference in pixel (RGB)
private static final int mThreshold = 10000; // Number of different pixels


private static int[] mPrevious = null;
private static int mPreviousWidth = 0;
private static int mPreviousHeight = 0;

/**
 * {@inheritDoc}
 */
@Override
public int[] getPrevious() {
    return ((mPrevious != null) ? mPrevious.clone() : null);
}

protected static boolean isDifferent(int[] first, int width, int height) {
    if (first == null) throw new NullPointerException();

    if (mPrevious == null) return false;
    if (first.length != mPrevious.length) return true;
    if (mPreviousWidth != width || mPreviousHeight != height) return true;

    int totDifferentPixels = 0;
    for (int i = 0, ij = 0; i < height; i++) {
        for (int j = 0; j < width; j++, ij++) {
            int pix = (0xff & ((int) first[ij]));
            int otherPix = (0xff & ((int) mPrevious[ij]));

            // Catch any pixels that are out of range
            if (pix < 0) pix = 0;
            if (pix > 255) pix = 255;
            if (otherPix < 0) otherPix = 0;
            if (otherPix > 255) otherPix = 255;

            if (Math.abs(pix - otherPix) >= mPixelThreshold) {
                totDifferentPixels++;
                // Paint different pixel red
                first[ij] = Color.RED;
            }
        }
    }

I'd like to understand this fully in order to be able to modify.

The line that really puzzles me is:

 int pix = (0xff & ((int) first[ij]));

What does it do?

thanks

Dave

I think that here it tries to get the value of the pixel but in a range of 0 to 255, so it uses the mask 0xFF to delete all the bits in a higher position than 8.

But I don't understand why it uses

            if (pix < 0) pix = 0;
            if (pix > 255) pix = 255;

When the pix variable can't be higher than 255

Forgive me if I explain something now that you know but I want to make this a self contained answer.

The colors of a pixel can be stored in an integer. An integer in Java consist of four bytes, a color typically (in this context) is represented with four bytes: One byte each for red, green, and blue, the last byte for transparency. The mix of the subpixels on screen results in the observed color.

So the following integer represents a color:

0    0    f    f    c    c    a    a      (Hexadecimal representation)
0000 0000 1111 1111 1100 1100 1010 1010   (Binary representation)
Transp.-- Red------ Green---- Blue-----   (Color interpretation)
                               16764074   (Decimal representation, quite useless here)

In this case the first two bytes (00) represent the transparency, ff the red subpixel, cc the green, aa the blue.

If we want to get only a single part of this, eg the blue subpixel, we need a bit mask.

0000 0000 1111 1111 1100 1100 1010 1010   (Binary representation)
&                                         (Binary AND: Return 1 if both bits are 1)
0000 0000 0000 0000 0000 0000 1111 1111   (Bitmask for blue, in hex 0x000000ff)
=
0000 0000 0000 0000 0000 0000 1010 1010

This is the result of the operation in the line you mention, it just uses the shorthand hex interpretation for the mask:

int pix = (0xff & ((int) first[ij]));

As the array first already is an int array the cast of first[ij] is useless.

If you want another part of the pixel, say the green part, you need to shift the mask (or use a hardcoded value) and need to shift back the result:

00ffccaa
&
0000ff00 Hardcoded, alternative: ff << 8
=
0000cc00

Shift the result to the rightmost position within the integer

0000cc00 >> 8 = 000000cc

Similar with 16 and 24 for red resp. transparency.

So the line gives you the value of the blue subpixel of the pixel. This value is in the range of 0..255, as these are the only values possible with eight bits (when interpreted as unsigned byte or stored in a Java int as it is done here; Java byte s are signed and wouldn't use that decimal representation but -128..127); any check for other values is useless here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM