JAVA: Image and Pixel Processing
Java
224
White

Nobody viết ngày 31/12/2021

Chao Cac Ban

I was absent for a very long time... To my wonder that Kipalog is still alive. It's a very good news.

Today I show you a brief tutorial about Image and Pixel Processing in JAVA. A proverb says "a picture is more than thousand words". How true! Even Confucius had to concede:

"If you tell me about it I'll forget it,
If you show it to me I'll remember it,
If you let me do it I'll understand it"

So. I show you and let you do so that you remember and understand what Image and Color are. First, let talk about a digital Image (or picture if you so will). What is a digital image?
alt text
Pic.1

A digital image is a group of PIXELS (PIX for Picture and EL for Element) which are represented by a combination of 3 different colors: RED, GREEN and BLUE or RGB for short. If a pixel can be made opaque or transparent it is an ARGB, where A is the controlling element. To represent the RGB or ARGB a computer needs at least 3 bytes (RGB) or 4 bytes (ARGB). And each byte can be displayed in 2 hex digits: 0x00 - 0xFF. For examples:

The color ORANGE or an ORANGE Pixel:
RGB:  0xFAA500
ARGB: 0x00FAA500 (fully or 100% transparent), 0x80FFFFFF (haft or 50% transparent), 0xFFFFFFFF (fully or 100% opaque)

As you see, with the ALPHA byte a Color (or Pixel) has 255 variable possibilities between total opaque to total transparent. Pic.2 shows you how an ARGB looks like:
alt text
Everything looks good. BUT why I have mentioned ARGB and RGBA? Well, the world is not a simpleton, but always a YING-YANG world. IBM computers usually work with BIG-ENDIAN and some others work with LITTLE ENDIAN. What is that, the endian? It's the byte-sequence to represent a number or an address. Examples:

The color 0x80FAA500 (a word or 32 bits)
                 byte 0     byte 1    byte 2   byte 3
LITTLE ENDIAN:     80         FA        A5      00
BIG ENDIAN         00         A5        FA      80

For human, the left digit is always higher than the next right digit and LITTLE ENDIAN is for human easier to understand than BIG ENDIAN. Luckily is that JAVA uses LITTLE ENDIAN to store its data (in files).
ARGB
alt text
RGBA
alt text

You can run this little program to see the ENDIAN of your computer:
Java:

public class MyEndian {
    public static void main(String... args) {
        System.out.println("->EndianOrder:"+java.nio.ByteOrder.nativeOrder());
    }
}

and the output from an INTEL PC will be:

->EndianOrder:LITTLE_ENDIAN

From the RGB or ARGB/RGBA structure it's obvious that the value of RGB (or ARGB/RGBA) can only be presented by an integer (or 4 bytes). If you are working with another OOPL than JAVA you have to be carefully to consider the ENDIAN because the interchange between bytes and integer is dependent on the endian. As said, JAVA stores and works with LITTLE ENDIAN. The conversion between 4 bytes and an integer is a straightforward work:

// from integer to byte[4]
int i = 0x010203;
byte[] b = new bytes[] { (byte)((i & 0xFF000000) >> 24), (byte)((i & 0xFF0000) >> 16), (byte)((i & 0xFF00) >> 8), (byte)(i & 0xFF) };
// from byte[4] to integer
int I = (b[0]&0xFF) << 24 + (b[1] &0xFF) << 16 + (b[2] & 0xFF) << 8 + b[3] & 0xFF;

You may wonder why I have to AND a byte with 0xFF, am I right? Well, JAVA doesn't have UNSIGNED byte, hence the term "byte & 0xFF" signifies an internal conversion of a byte to an int before the AND operation can be executed. Example:

byte b = 0xFF; // as - 1 from a range between -1....-127 0....127 or 0xFF....x81 x00....0x7F
int i = (int) b;  // i yields -1 or 0xFFFFFFFF
int j = (int)(b & 0xFF); // j = 255 = 0xFFFFFFFF & 0x000000FF = 0x000000FF

IT or Computer Science (CS) without Mathematics is like a flower without water. If you don't master the most basic mathematical knowledge you wither like a flower. CS works with binary system and knows only ONE operation: addition. The other operations (subtract, multiplication and division) are derived from Addition. Binary means 0 (zero) or 1 (ONE). Not zero is one and vice versa. In Math an opposite of a binary number can be represented by either the FIRST Complement or the SECOND Complement:

  • First Complement or 1st Complement is the reverse of each digit. Example: 15 = b1111, the 1st complement is 0000.
  • Second Complement or 2nd Complement is the addition of the 1st Complement with 1. Example: 15 = b1111 +b1 = b10000.

With the complements Sub, Mul and Div can be implemented. I don't go into details with the MUL/DIV binary operation but show you how the Sub works. The algorithm is as following:

  • The subtractor is converted to the 2nd-Complement,
  • The 2nd-Complement is added to the subtrahend

Depend on the sign the result could exceed the digit number of subtractor and subtrahend. If so, it's an OVERFLOW and it can be ignored.
Example: 4-digit bits, the 1st digit is the sign (0: plus, 1: minus)

a = 0111      (+7)
b = 0010      (+2)
________________
a - b = 5 or 0101

1) b to 1st complement: 0010 becomes 1101
2) 1st complement to 2nd complement by add 1 or 1101 + 0001 = 1110
3) a + 2nd complement: 0111 + 1110 = (1)0101 = 5, overflow 1
  • Multiplication is the addition of the multiplicand by multiplicator times.
  • Division is the subtraction of the dividend to the divisor until the Subtraction result is 0 or less than the divisor. The number of subtraction is the quotient and the last subtraction result is the rest (e.g. 12 : 2 yields 6x subtraction and the last result is 0. Quotient = 6, Rest = 0).

In reality we rarely deal with binary operation, but the binary knowledge helps us to derive and to estimate an operation. Addition is the fastest, then Subtraction, then Multiplication and the slowest is Division.

Back to an Image and Pixel.
In the past we have to take an image on a film and develop the image into a picture. The image is the negative, and the Picture is the final result. Similar to that, a digital image can be easily "reversed" into a negative by complementing the pixels. A Pixel is an integer or a 4 bytes value. To "negative" a Pixel we have to partition it into 4 bytes as I showed you above and then complement each byte with 255 (or 0xFF):

int cyan = 0x00FFFF;
int red  = (cyan & 0xFF0000) >> 16;
int green = (cyan & 0xFF00) >> 8;
int blue = cyan & 0xFF
// negative of cyan
int negCyan = ((0xFF - red) << 16) | ((0xFF - green) << 8) | (0xFF -blue);

And every image is consisted by width * height pixels (see Pic.1 of the 1st session. The width is the X axis, the height is the Y axis). The negative of an image is then:

    BufferedImage img = ImageIO.read(new File(imgFile));
    int width  = img.getWidth();
    int height = img.getHeight();
    for(int y = 0; y < height; ++y)
    for(int x = 0; x < width; ++x) {
      int p = img.getRGB(x,y); // get the pixel at location x, y
      // negate RGB by subtraction from 255
      int a = p & 0xFF000000;
      int r = 255 - (p >> 16) & 0xFF;
      int g = 255 - (p >> 8)  & 0xFF;
      int b = 255 - p & 0xFF;
      //set new RGB value
     img.setRGB(x, y,  a | (r << 16) | (g << 8) | b);
    }

alt text

More Click HERE (Congdongjava.com)

Note:
It's a long tutorial and I have no interest to repeat the whole tutorial here on Kipalog.com. If the admins think that my blog is an ad then pls. delete it and remove my account from Kipalog.com

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Nobody

20 bài viết.
560 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
1 0
(Ảnh) I found this question in a Vietnamese forum ((Link)). The questioner is certainly not a man who's studied Computer Science (or in Vietnamese...
Nobody viết 4 tháng trước
1 0
White
1 0
This tutorial is a summary of the two last tutorials 1. OCR: (Link) 2. JAVA: (Link) With the knowledge we have about the way how to process an Ima...
Nobody viết 3 tháng trước
1 0
White
1 0
Hi Some developers whose native language is NOT English seem to be either bad in English or too lazy to read the APIs. However I have an impressio...
Nobody viết 2 tháng trước
1 0
Bài viết liên quan
White
2 0
Trong bài viết này, một số hình ảnh hoặc nọi dung có thể bị thiếu do quá trình chế bản. Vui lòng xem nội dung ở blog gốc sau: (Link) (Link), chúng...
programmerit viết gần 7 năm trước
2 0
White
0 0
Giới thiệu Trong bài hôm nay chúng ta sẽ tìm hiểu cách handle request POST của Spring Boot. Trước đó, bạn nên biết 1. 「Spring Boot 8」Tạo Web He...
https://loda.me viết gần 3 năm trước
0 0
Male avatar
0 0
https://grokonez.com/deployment/vultr/howtoinstalljavainubunturemoteservervutrhostingvpsexample How to install Java on Ubuntu Remote Server – Vutr...
loveprogramming viết 1 năm trước
0 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
20 bài viết.
560 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!