简体   繁体   中英

How to convert Colors to Grayscale in java with just the java.io.*; library?

Well, i got this.. cause in my place they request it like that.. Well i have this: //some variables and coments are a possible code.. But i mean i don't know how to do it exactly, i found on internet that to convert R is the byte is in *0.21 with G is *0.71 i guess and blue is * 0.07. I just can use that library java.io.*; and i'm working with BMP format images of 1024 x 768, if you can help me, or you want me to be more specific please tell me. i don't know if i have to add another variables or to take some out, or to modify, please help me. I'm not so new in this language, but i'm not an expert. The code is right here:

import java.io.*;

public class Grayscale{

FileInputStream image;
FileOutputStream img;
byte[] datos;
int i;
int cont;

public Grayscale(String nombre)throws Exception{

    this.image = new FileInputStream(nombre);
    this.img = img;
    this.datos = new byte[image.available()];
    this.i = 54;
    this.cont = 1;
}

public void gray()throws Exception{

    image.read(datos);
    img = new FileOutputStream("grayscale.bmp");

    while(i<datos.length){
        if(cont == 1){
            datos[i] = datos[i] ;//* 0.21;
            cont++;
        } else if(cont == 2){
            datos[i] = datos [i] ;//* 0.71;
            cont++;
        } else if(cont == 3){
            datos[i] = datos[i] ;//* 0.07;
            cont++;
        }else{
            cont = 1;
        }
        i++;
    }
    img.write(datos);
}

}

Most image formats have header information before the pixel data, so when you're reading these types of files, you need to take that into consideration...

Frankly, it's much easier to rely on pre-existing library where you can.

ImageIO allows you to read and write a number of different file formats, including BMP.

Take a look at

The next decision is - do you convert the image yourself or use a pre-existing filter. You'll have to do some of your own metrics, but in the past, I've found pixel manipulation of an image to be slow, slower than the in built filters at the very least...

在此处输入图片说明

Original, manual grayscale, automatical/filter grayscale

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class GrayScaleImage {

    public static void main(String[] args) {
        new GrayScaleImage();
    }

    public GrayScaleImage() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridLayout(0, 3));
            try {
                BufferedImage master = ImageIO.read(new File("/path/to/file.bmp"));
                BufferedImage gray = ImageIO.read(new File("/path/to/file.bmp"));

                // Manual manipulation...
                for (int x = 0; x < gray.getWidth(); x++) {
                    for (int y = 0; y < gray.getHeight(); y++) {
                        Color color = new Color(gray.getRGB(x, y));
                        int red = color.getRed();
                        int green = color.getGreen();
                        int blue = color.getBlue();

                        red = green = blue = (int)(red * 0.299 + green * 0.587 + blue * 0.114);
                        color = new Color(red, green, blue);
                        int rgb = color.getRGB();
                        gray.setRGB(x, y, rgb);
                    }
                }

                BufferedImage grayScale = ImageIO.read(new File("/path/to/file.bmp"));

                // Automatic converstion....
                ColorConvertOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
                op.filter(grayScale, grayScale);

                add(new JLabel(new ImageIcon(master)));
                add(new JLabel(new ImageIcon(gray)));
                add(new JLabel(new ImageIcon(grayScale)));
            } catch (IOException ex) {
                Logger.getLogger(GrayScaleImage.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }        
}

Now, writing the image (which is not demonstrated above) would be as simple as...

ImageIO.write(grayScale, "BMP", new File("/path/to/grayscale file.bmp"));
// constant factors
            final double GS_RED   = 0.299;
            final double GS_GREEN = 0.587;
            final double GS_BLUE  = 0.114;

Now retrieve each and gett it's red, blue, green component and alpha if exist and multiply them with their corresponding factor.

R = G = B = (int)(GS_RED * R + GS_GREEN * G + GS_BLUE * B);

For each pixel you have the RGB values, take only the R value and copy it to G and B. So that each pixel will contain the red value in the 3 RGB this will cause the image to be gray. Example. data [0]=123 //red data [1]=43 //Green data [2]=78 //blue Then data [0]=123 data [1]=123 data [2]=123

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