I wanted to read a grayscale image values into a 2d array, change the values of the 2d array and create a new grayscale image from the modified values of 2d array.
Following is the code to read the grayscale image into 2D array(arr[][]).
package dct;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.io.File;
import javax.imageio.ImageIO;
/**
*
* #author jain
*/
public class writeGR {
public static void main(String[] args)
{
File file = new File("lightning.jpg");
BufferedImage img = null;
try
{
img = ImageIO.read(file);
}
catch(Exception e)
{
e.printStackTrace();
}
int width = img.getWidth();
int height = img.getHeight();
int[][] arr = new int[width][height];
Raster raster = img.getData();
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
arr[i][j] = raster.getSample(i, j, 0);
}
}
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
image.setData(raster);
//
//BufferedImage image1 = image;
try
{
File ouptut = new File("grayscale.png");
ImageIO.write(image, "png", ouptut);
}
catch(Exception e)
{
e.printStackTrace();
}
}// main
}
Now I want to change the "arr[][]" vlaues and create a new grayscale image out of that. How to do this?
The above problem can be solved by the following code:
for(int i=0;i<width;i++)
{
for(int j=0;j<height;j++)
{
tempArr[0] = 100;
raster1.setPixel(i, j, tempArr);
}
}
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
image.setData(raster1);
try
{
File ouptut = new File("change.png");
ImageIO.write(image, "png", ouptut);
}
catch(Exception e)
{
e.printStackTrace();
}
Related
This question already has answers here:
How to combine multiple PNGs into one big PNG file?
(10 answers)
Closed 2 years ago.
My case is what I need to add several barcodes (png) which I generated using Barcode4j library in one png file. I couldn't find any examples, also couldn't make up my mind to solve it. So any help will be appreciated.
Well, I generate barcodes in usual way (throug for) and collecte them in a list of bufferedImages (List). Now I need to glue this images in one.
My code:
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BitmapCanvasProvider canvas = new BitmapCanvasProvider(baos, "image/x-png", 300, BufferedImage.TYPE_BYTE_BINARY, false, 0);
List<BufferedImage> bufferedImageList = new ArrayList<>(); // list for bufferedImages
for (int i = 0; i < barcodesList.size(); i++) {
try {
Code128Bean code128 = new Code128Bean();
code128.setHeight(15f);
code128.setModuleWidth(0.3);
code128.setQuietZone(10);
code128.doQuietZone(true);
code128.generateBarcode(canvas, (String) barcodesList.get(i));
bufferedImageList.add(canvas.getBufferedImage()); // collect images of barcode in cicle
canvas.finish();
} catch (Exception e) {
e.printStackTrace();
}
}
FileOutputStream fos = new FileOutputStream(barcodePath.toString());
// to do smth to make one png from collected images
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
Well, my code which combine several barcodes looks like this
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BitmapCanvasProvider canvas = new BitmapCanvasProvider(baos, "image/x-png", 300, BufferedImage.TYPE_BYTE_BINARY, false, 0);
List<BufferedImage> bufferedImageList = new ArrayList<>(); // list for bufferedImages
int sumHeight = 0;
int sumWhide = 0;
int columns = 2;
int rows = 0;
for (int i = 0; i < barcodesList.size(); i++) {
try {
Code128Bean code128 = new Code128Bean();
code128.setHeight(15f);
code128.setModuleWidth(0.3);
code128.setQuietZone(10);
code128.doQuietZone(true);
code128.generateBarcode(canvas, (String) barcodesList.get(i));
sumHeight = sumHeight + canvas.getBufferedImage().getHeight();
sumWhide = sumWhide + canvas.getBufferedImage().getWidth();
bufferedImageList.add(canvas.getBufferedImage()); // collect images of barcode in cycle
canvas.finish();
} catch (Exception e) {
e.printStackTrace();
}
}
double dbl = barcodesList.size() / (double) columns;
rows = (int)Math.ceil(dbl);
int oneWhide = sumWhide / barcodesList.size();
int imgWhide = oneWhide * columns;
int oneHeight = sumHeight / barcodesList.size();
int imgHeight = oneHeight * rows;
BufferedImage bigImage = new BufferedImage(imgWhide, imgHeight, BufferedImage.TYPE_BYTE_BINARY);
Graphics g = bigImage.getGraphics();
int x = 0;
int y = 0;
for (BufferedImage bufferedImage : bufferedImageList) {
g.drawImage(bufferedImage, x, y, null);
x += oneWhide;
if(x >= bigImage.getWidth()){
x = 0;
y += bufferedImage.getHeight();
}
}
ImageIO.write(bigImage,"png",new File(barcodePath.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
Actually I am working on a application where I need to change the flooring of a room. The application's back end is in java.Suppose this is the room.
Room whose floor needs to be changed
Room after floor removed
Carpet which needs to be laid
Result after executing the code
I have removed the floor of the room using software like photoshop. Now I need to add new carpet floor to that image. The carpet flooring must be dynamic where a user selects any carpet and the images replaces after rendering.
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class FloorChange {
public static void main(String[] args) {
int width = 1920; // width of the image
int height = 1080; // height of the image
// For storing image in RAM
BufferedImage image = null;
BufferedImage background = null;
BufferedImage finalImage = null;
// READ IMAGE
try {
File input_file = new File("room.png"); // image file path
File floor_tile = new File("milkyway.jpg"); // image file path
FloorChange floorChange = new FloorChange();
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
background = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
finalImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
System.out.println("Reading complete.");
} catch (IOException e) {
System.out.println("Error: " + e);
}
try {
Graphics2D g = finalImage.createGraphics();
g.drawImage(background, 0, 0, null);
g.drawImage(image, 0, 0, null);
File output_file = new File("floor1.png");
ImageIO.write(finalImage, "png", output_file);
System.out.println("Writing complete.");
} catch (IOException e) {
System.out.println("Error: " + e);
}
}
private BufferedImage resizeImage(BufferedImage originalImage, int type) {
int IMG_WIDTH = 1920;
int IMG_CLAHEIGHT = 1080;
BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_CLAHEIGHT, type);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_CLAHEIGHT, null);
g.dispose();
return resizedImage;
}
I have replaced the floor but the image was stretched and if I repeat the image it gives lines between each carpet. And also the perspective of the imag e is not proper.
I am reading tiff file and extracting bounding box images now based on confidence value of each character I want to separate some images and consolidate to one image file for training dataset.
BufferedImage[] input = new BufferedImage[count-1];
//Load each input image.
for(int index=0; index<input.length; index++) {
try {
File f = new File("folder_path\\"+img_"+
(index+1)+".tiff");
input[index] = ImageIO.read(f);
}
catch(Exception e) {
e.printStackTrace();
}
}
int offset = 5, width=0, height=input[0].getHeight();
for(int index=0; index<input.length; index++) {
width+=input[index].getWidth();
if(height<input[index].getHeight())
{
height=input[index].getHeight();
}
}
width+=count*offset;
height+=offset;
//Create Output image
BufferedImage output = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = output.createGraphics();
Color oldColor = g2.getColor();
//fill background
g2.setPaint(Color.WHITE);
g2.fillRect(0, 0, width, height);
//draw image
g2.setColor(oldColor);
int xcordinate=0;
for(int index=0; index<input.length; index++) {
g2.drawImage(input[index], null, xcordinate, 0);
xcordinate+=input[index].getWidth()+offset;
}
g2.dispose();
File merged = new File("folder_path\\"+merged_2_new.tiff");
try {
ImageIO.write(output, "tiff", merged);
}
catch(Exception e) {
e.printStackTrace();
}
So I wrote this program to read an image and change some of it's colors:
public class MorphImage {
private final String URL = "pic1.jpg";
public static void main(String[] args) {
try {
new MorphImage();
} catch (IOException e) {
e.printStackTrace();
}
}
public MorphImage() throws IOException {
BufferedImage image = readImage(URL);
pointOp(image, 50, 75);
}
/**
* Read and create a bufferedImage from an URL.
*
* #param URL
* #return
*/
private BufferedImage readImage(String URL) {
URL url = getClass().getResource(URL);
File file = new File(url.getPath());
BufferedImage bimg = null;
try {
bimg = ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
}
return bimg;
}
/**
* Uses a BufferedImage to create a new copy of it with altered values.
*
* #param img
* #throws IOException
*/
private void pointOp(BufferedImage img, int con, int brig) throws IOException {
int width = img.getWidth();
int height = img.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
WritableRaster inraster = img.getRaster();
WritableRaster outraster = image.getRaster();
for (int i = 0; i < width; i++)
for (int j = 0; j < height; j++) {
int value = inraster.getSample(i, j, 0);
outraster.setSample(i, j, 0, 255 - value);
}
ImageIO.write(image, "PNG", new File("Morphed " + URL));
System.out.println("Morphed");
}
}
It work great on my laptop running Windows 10, but when I cloned the repo unto my pc running Windows 8.1, it can't find the the image "pic1.jpg" anymore. It throws IIOException Can't read input file. Both computers are running identical setups of JDK and Eclipse. I got all my files in the same package:
imager
-src
-main
-MorphImage.java
-pic1.jpg
Do anyone know what's wrong here?
I am reading two images in a servlet and need to show both at the same time.
Currently, only one image is shown (one that is written first). unable to write another image.
I do not get any error.
My servlet code goes like this :
BufferedImage buffImageA = ImageIO.read(getServletContext().getResourceAsStream("/images/3520276097315A.jpg"));
BufferedImage buffImageB = ImageIO.read(getServletContext().getResourceAsStream("/images/3520276097315B.jpg"));
logger.logDebug("Images has been read");
watermark(buffImageA,ApplicationConfig.WATERMARK_TEXT);
watermark(buffImageB,ApplicationConfig.WATERMARK_TEXT);
byte[] resultDataA = encodeJPEG(buffImageA, 100);
byte[] resultDataB = encodeJPEG(buffImageB, 100);
byte[] combinedImage = new byte[resultDataA.length+resultDataB.length];
for(int i=0; i<resultDataA.length ;i++){
combinedImage[i] = resultDataA[i];
}
for(int i=resultDataA.length; i<resultDataB.length ;i++){
combinedImage[i] = resultDataB[i];
}
response.setContentType("image/jpeg");
response.setContentLength(resultDataA.length + resultDataB.length);
OutputStream os = response.getOutputStream();
os.write(combinedImage);
os.close();
//Watermarking process goes here
private void watermark(BufferedImage original, String watermarkText) {
}
private byte[] encodeJPEG(BufferedImage image, int quality) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream((int) ((float) image.getWidth() * image.getHeight() / 4));
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(baos);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image);
quality = Math.max(0, Math.min(quality, 100));
param.setQuality((float) quality / 100.0f, false);
encoder.setJPEGEncodeParam(param);
encoder.encode(image);
byte[] result = baos.toByteArray();
baos.close();
return result;
}
I have tried using ImageIO.write to write the image but failed to get what is desired.
Your second for loop must be like this:
for(int i=resultDataA.length; i<resultDataB.length+resultDataA.length ;i++){
combinedImage[i] = resultDataB[i-resultDataA.length];
}
EDIT :
This is a compilable, runnable example close to what you're expecting :
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import java.awt.Graphics;
public class Essai2 {
public static void main(String[] args) {
try {
byte[] imageInByte;
BufferedImage originalImage1 = ImageIO.read(new File("essai1.jpg"));
BufferedImage originalImage2 = ImageIO.read(new File("essai2.jpg"));
// convert BufferedImage to byte array
ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
ImageIO.write(originalImage1, "jpg", baos1);
ImageIO.write(originalImage2, "jpg", baos2);
baos1.flush();
baos2.flush();
byte[] ba1 = baos1.toByteArray();
byte[] ba2 = baos2.toByteArray();
imageInByte = new byte[ba1.length + ba2.length];
//System.out.println(new String(imageInByte));
System.arraycopy(ba1, 0, imageInByte, 0, ba1.length);
//System.out.println(new String(imageInByte));
System.arraycopy(ba2, 0, imageInByte, ba1.length, ba2.length);
//System.out.println(new String(imageInByte));
baos1.close();
baos2.close();
// convert byte array back to BufferedImage
InputStream in = new ByteArrayInputStream(imageInByte);
int w = Math.max(originalImage1.getWidth(), originalImage2.getWidth());
//int h = Math.max(originalImage1.getHeight(), originalImage2.getHeight());
int h = originalImage1.getHeight() + originalImage2.getHeight();
BufferedImage bImageFromConvert = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
//BufferedImage bImageFromConvert = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR );
//BufferedImage bImageFromConvert = ImageIO.read(in);
Graphics g = bImageFromConvert.getGraphics();
g.drawImage(originalImage1, 0, 0, null);
g.drawImage(originalImage2, 0, originalImage1.getHeight(), null);
ImageIO.write(bImageFromConvert, "jpg", new File("result.jpg"));
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
essai1.jpg:
essai2.jpg:
result.jpg:
I haven't found for the moment why there's a third color added to result.jpg. But I think this example can help you and I will fix my code asap.
EDIT2 :
Change :
BufferedImage bImageFromConvert = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
To :
BufferedImage bImageFromConvert = new BufferedImage(w, h, originalImage1.getType());
And it will works fine.
result.jpg: