Java - Convert Image to Greyscale Using Array of Filenames - java

Is it possible to feed an array of image names into code which converts images to greyscale?
I am able to convert an image into greyscale by using this code:
public static void makeGrey() {
try{
//Read in original image.
BufferedImage image = ImageIO.read(new File("images\\012.jpg"));
//Obtain width and height of image.
double image_width = image.getWidth();
double image_height = image.getHeight();
BufferedImage bimg = null;
BufferedImage img = image;
//Draw the new image.
bimg = new BufferedImage((int)image_width, (int)image_height, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D gg = bimg.createGraphics();
gg.drawImage(img, 0, 0, img.getWidth(null), img.getHeight(null), null);
//Save new greyscale (output) image.
String temp = "_inverted";
File fi = new File("images\\" + temp + ".jpg");
ImageIO.write(bimg, "jpg", fi);
}
catch (Exception e){
System.out.println(e);
}
}
However, this code only works on a single file at a time and I would like to know how to go about getting it to work through all files located in the images directory?
I have created an array which goes through the images directory and stores the names of all of the files and I would like to know how to pass these filenames into my makeGrey() method?
static File dir = new File("images");
static File imgList[] = dir.listFiles();
public static void listFiles(String imageName) {
if(dir.isDirectory()){
for(File img : imgList){
if(img.isFile()){
MakeGrey.makeGrey();
}
}
}
Thank you.

Your makeGray() method should look like this:
public static void makeGrey(File image) {
try{
//Read in original image.
BufferedImage inputImage = ImageIO.read(image);
...
...
//Save new greyscale (output) image. (Or you'll rewrite same image all the time...)
File fi = new File("images\\inverted_" + image.getName()
...
...
and other part of the code should call it like this:
static File dir = new File("images");
static File imgList[] = dir.listFiles();
public static void listFiles(String imageName) {
if(dir.isDirectory()){
for(File img : imgList){
if(img.isFile()){
MakeGrey.makeGrey(img);
}
}
}

Related

Compress an image without specifying the type of image

This code is to compress a jpeg image, but if I want to compress an image without specifying the type of image, how can I do that? , How do I modify the code ?
File originalImage = new File("C:\\Users\\Super\\Desktop\\man.jpg");
File compressedImage = new File("C:\\Users\\Super\\Desktop\\compressedImage.jpg");
try{
compressJPEGImage(originalImage, compressedImage,0.5f );
System.out.println("Done!");
}
catch(IOException e){
}
}
public static void compressJPEGImage(File originalImage , File compressedImage , float
compressionQuality) throws IOException{
RenderedImage image = ImageIO.read(originalImage);
ImageWriter jpegwriter = ImageIO.getImageWritersByFormatName("jpg").next();
ImageWriteParam jpegWriteParam=jpegwriter.getDefaultWriteParam();
jpegWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
jpegWriteParam.setCompressionQuality(compressionQuality);
try(ImageOutputStream output=ImageIO.createImageOutputStream(compressedImage)){
jpegwriter.setOutput(output);
IIOImage outputImage = new IIOImage(image,null,null);
jpegwriter.write(null,outputImage,jpegWriteParam);
}
jpegwriter.dispose();
}
Convert image to base64 or byte array of any type, then you can try for compressing it.

Output image becomes black after conversion from FileInputStream to Image

I am trying to merge two TIFF images which are in form of FileInputStream into a single Tiff image. Although the image is getting merged the output file is coming up as Black. While comparing the original image and the converted image I could see that the bit depth of the converted image changes to 1. Could anybody provide a solution to this?
The code that I am using is:
public class MergerTiffUsingBuffer {
public static void main(String[] args) {
File imageFile1 = new File("D:/Software/pdfbox-1.3.1.jar/tiff/FLAG_T24.TIF");
File imageFile2 = new File("D:/Software/pdfbox-1.3.1.jar/tiff/CCITT_3.TIF");
try {
FileInputStream fis1 = new FileInputStream(imageFile1);
FileInputStream fis2 = new FileInputStream(imageFile2);
List<BufferedImage> bufferedImages=new ArrayList<>();
List<FileInputStream> inputStreams=new ArrayList<>();
inputStreams.add(fis1);
inputStreams.add(fis2);
Iterator<?> readers = ImageIO.getImageReadersByFormatName("tiff");
ImageReader reader = (ImageReader) readers.next();
for(FileInputStream inputStream:inputStreams){
ImageInputStream iis = ImageIO.createImageInputStream(inputStream);
reader.setInput(iis);
ImageReadParam param = reader.getDefaultReadParam();
Image image = reader.read(0, param);
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
OutputStream out = new FileOutputStream("D:/Software/pdfbox-1.3.1.jar/tiff/MergedTiff.TIF");
BufferedImage binarized = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(),BufferedImage.TYPE_BYTE_BINARY);
ImageIO.write(binarized, "tiff", out);
bufferedImages.add(bufferedImage);
}
System.out.println(bufferedImages.size());
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
You seem to be a little confused about how to copy image data. Simply creating a new, blank image, by passing the dimensions of another image, will not copy it... So a fully black image is what I would expect after running your code.
Replace your for loop with something like this:
for (FileInputStream inputStream : inputStreams) {
ImageInputStream iis = ImageIO.createImageInputStream(inputStream);
reader.setInput(iis);
BufferedImage image = reader.read(0, null); // a) BufferedImage is returned! b) null param is fine!
BufferedImage binarized = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
// The following 7 lines is the important part you were missing:
Graphics2D g = binarized.createGraphics();
try {
g.drawImage(image, 0, 0, null);
}
finally {
g.dispose();
}
OutputStream out = new FileOutputStream("D:/Software/pdfbox-1.3.1.jar/tiff/MergedTiff.TIF");
ImageIO.write(binarized, "tiff", out); // You probably want to check return value (true/false)!
bufferedImages.add(image);
}

Automatically capture clip board data and save it into a file

Capture a image from the clipboard whenever Print screen is pressed and save it in a file (.doc) using java
Main aim is to copy the data from the clipboard and automatically save it into local disk without going to the desired program (i.e MS Word)- click new - pressing (Ctrl+V) to paste and save it with a name.
The code should perform all of the above three steps automatically.
My Source Code
public class CaptureScreenShot {
private static String DIR ="C:\\QUIS\\";
private static JTextField txtDocNumber;
public static void main(String[] args) throws Exception{
txtDocNumber = new JTextField();
Robot robot = new Robot();
Dimension d = new Dimension(Toolkit.getDefaultToolkit().getScreenSize());
int width = (int) d.getWidth();
int height = (int) d.getHeight();
robot.delay(5000);
Image image = robot.createScreenCapture(new Rectangle(0, 0, width,
height));
BufferedImage bi = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
g.drawImage(image, 0, 0, width, height, null);
String fileNameToSaveTo = "C:/QUIS/screenCapture_" + createTimeStampStr() + ".PNG";
String newFile = "C:/QUIS/x" + ".org";
File newFilee = new File(newFile);
writeImage(bi, fileNameToSaveTo, "PNG");
System.out.println("Screen Captured Successfully and Saved to:\n"+fileNameToSaveTo);
Desktop desktop = Desktop.getDesktop();
writeImage(bi, newFile, "org");
desktop.open(newFilee);
}
public static int writeImage(BufferedImage img, String fileLocation,
String extension) {
try {
BufferedImage bi = img;
File outputfile = new File(fileLocation);
ImageIO.write(bi, extension, outputfile);
} catch (IOException e) {
e.printStackTrace();
}
return 1;
}
public static String createTimeStampStr() throws Exception {
Calendar mycalendar = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd_hhmmss");
String timeStamp = formatter.format(mycalendar.getTime());
return timeStamp;
}
}
If you are not particular about a java code, you could use some screen capture tool instead. Snagit is a good tool. You could find it on http://www.techsmith.com/snagit.html
Try this sample code, according to your question it will copy contents from clipboard and will generate image file
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
try {
//Get data from clipboard and assign it to an image.
//clipboard.getData() returns an object, so we need to cast it to a BufferdImage.
BufferedImage image = (BufferedImage)clipboard.getData(DataFlavor.imageFlavor);
//file that we'll save to disk.
File file = new File("image.jpg");
//class to write image to disk. You specify the image to be saved, its type,
// and then the file in which to write the image data.
ImageIO.write(image, "jpg", file);
}

Java - Generate New Filename for New BufferedImage Files

Is it possible to generate a new image name for each image that is processed using the following code (I have highlighted the relevant section)?
public static void makeBinary(File image) {
try{
//Read in original image.
BufferedImage inputImg = ImageIO.read(image);
//Obtain width and height of image.
double image_width = inputImg.getWidth();
double image_height = inputImg.getHeight();
//New images to draw to.
BufferedImage bimg = null;
BufferedImage img = inputImg;
//Draw the new image.
bimg = new BufferedImage((int)image_width, (int)image_height, BufferedImage.TYPE_BYTE_BINARY);
Graphics2D gg = bimg.createGraphics();
gg.drawImage(img, 0, 0, img.getWidth(null), img.getHeight(null), null);
// ************* THIS IS WHERE I AM HAVING DIFFICULTY ***************
//Save new binary (output) image.
String temp = "_inverted";
File fi = new File("images\\" + temp + ".jpg");
ImageIO.write(bimg, "jpg", fi);
// ******************************************************************
}
catch (Exception e){
System.out.println(e);
}
}
I have 300 images, numbered 001.jpg - 300.jpg, and what I would like is for each new outputted image to be named something along the lines of, binary_001.jpg - binary_300.jpg.
The method that calls makeBinary() is located in another class and is:
public static void listFiles() {
File dir = new File("images");
File imgList[] = dir.listFiles();
if(dir.isDirectory()){
for(File img : imgList){
if(img.isFile()){
MakeBinary.makeBinary(img);
System.out.println(img + ": processed successfully.");
}
else{
System.out.println("Directory detected; skipping to next file,");
}
}
}
}
How can I go about achieving this?
Many thanks.
Get the filename from your File image parameter and add it to the new filename:
String temp = image.getName() + "_inverted";
File fi = new File("images\\" + temp + ".jpg");
ImageIO.write(bimg, "jpg", fi);
You can just concatenate name from the original image (in your code 'image' you pass to ImageIO with the string "_inverted", this way you would have original name for each image you process: image.jpg -> image_inverted.jpg
File fi = new File("images\\" + "binary_" + image.getName());
Should do the trick.
Or even better:
File fi = new File(image.getParent(), "binary_" + image.getName());

My batch jpg resizer works with color images, but grayscale ones become washed out

I've been having a problem with my Java program. It's for resizing images. You drop it into a folder and run it, and it creates a new folder with the resized images. It works great on color, but it has a problem with grayscale. The images are converted, but they become lighter and more washed out, as if someone has messed with the curves or levels. All the input files and output files are sRGB color space jpegs, saved in RGB color mode. I have thousands of 50 megapixel film scans I'm trying to convert down to 15 megapixels or less. Any help or ideas anyone could offer would be most appreciated. The programs full code is below, it's about 130 lines. I have a feeling the problem may be in the toBufferedImage function but I'm lost as to what it could be.
package jpegresize;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.io.*;
import javax.imageio.*;
import javax.imageio.stream.*;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
System.out.println("JPEGResize running . . .");
int max_side = 4096;
float quality = 0.9f;
if(args.length == 0) System.out.println("No maximum side resolution or compression quality arguments given, using default values.\nUsage: java -jar JPEGResize.jar <maximum side resolution in pixels> <quality 0 to 100 percent>");
if(args.length >= 1) max_side = Integer.parseInt(args[0]);
if(args.length >= 2) quality = Float.parseFloat(args[1]) / 100.0f;
System.out.println("Maximum side resolution: " + max_side);
System.out.println("Compression quality: " + (quality * 100) + "%");
File folder = new File(".");
File[] listOfFiles = folder.listFiles(new JPEGFilter());
for(int i = 0; i < listOfFiles.length; i++) {
System.out.println("Processing " + listOfFiles[i].getName() + " . . .");
resizeFile(listOfFiles[i].getName(), max_side, quality);
System.out.println("Saved /resized/" + listOfFiles[i].getName());
}
System.out.println("Operations complete.");
}
public static void resizeFile(String filename, int max_side, float quality) {
try
{
BufferedImage input_img = ImageIO.read(new File(filename));
double aspect_ratio = ((double)input_img.getWidth()) / ((double)input_img.getHeight());
int width, height;
if(input_img.getWidth() >= input_img.getHeight()) {
width = max_side;
height = (int)(((double)max_side) / aspect_ratio);
}
else {
width = (int)(((double)max_side) * aspect_ratio);
height = max_side;
}
Image scaled_img = input_img.getScaledInstance(width, height, Image.SCALE_SMOOTH);
BufferedImage output_img = toBufferedImage(scaled_img);
Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter writer = (ImageWriter)iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(quality);
File doesDirExist = new File("resized/");
if(!doesDirExist.exists())
new File("resized").mkdir();
File file = new File("resized/" + filename);
FileImageOutputStream output = new FileImageOutputStream(file);
writer.setOutput(output);
IIOImage image = new IIOImage(output_img, null, null);
writer.write(null, image, iwp);
writer.dispose();
}
catch (IOException e)
{
e.printStackTrace();
}
}
// This method returns a buffered image with the contents of an image
public static BufferedImage toBufferedImage(Image image) {
if (image instanceof BufferedImage) {
return (BufferedImage)image;
}
// This code ensures that all the pixels in the image are loaded
image = new ImageIcon(image).getImage();
// Create a buffered image with a format that's compatible with the screen
BufferedImage bimage = null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
try {
// Determine the type of transparency of the new buffered image
int transparency = Transparency.OPAQUE;
// Create the buffered image
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
bimage = gc.createCompatibleImage(
image.getWidth(null), image.getHeight(null), transparency);
} catch (HeadlessException e) {
// The system does not have a screen
}
if (bimage == null) {
// Create a buffered image using the default color model
int type = BufferedImage.TYPE_INT_RGB;
bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
}
// Copy image to buffered image
Graphics g = bimage.createGraphics();
// Paint the image onto the buffered image
g.drawImage(image, 0, 0, null);
g.dispose();
return bimage;
}
}
class JPEGFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return (name.toLowerCase().endsWith(".jpg")) || (name.toLowerCase().endsWith(".jpeg"));
}
}
If jdk's classes and methods are buggy, report the bug to oracle (oh! I wish I could go on saying to SUN..).
And, while the next release will correct the bug ;), try some work arounds, scaling image by yourself like proposed here.
Regards,
Stéphane
In your code, you assume jpeg are encoded in RGB, but that's not always the case. It's also possible to encode 8 bit gray scaled jpeg. So I suggest that you try this when building your BufferedImage, replace :
BufferedImage.TYPE_INT_RGB;
by
BufferedImage.TYPE_BYTE_GRAY;
and see if it works for those images.
If so, then you still have to find out a way to determine the encoding type to automatically change the type of BufferedImage color encoding to use, but you will be one stop closer.
Regards,
Stéphane

Categories

Resources