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();
}
}
Related
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();
}
I have been trying to hide an image in another image(both of same type) by making changes in the pixels.But it gives an error like this:
Exception in thread "main" java.lang.NumberFormatException: For input
string: "010010101101111111"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at Image.main(Image.java:160)**
The code is shown as below:
public class Image {
public static void main(String argv[]) throws Exception
{
String imageFile1 = "C:/Users/Desktop/1.jpg";
String imageFile2 = "C:/Users/Desktop/2.jpg";
File file1 = new File(imageFile1);
FileInputStream fis1 = null;
try {
fis1 = new FileInputStream(imageFile1);
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
File file2 = new File(imageFile2);
FileInputStream fis2 = null;
try {
fis2 = new FileInputStream(imageFile2);
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
BufferedImage oimage1 = ImageIO.read(file1);
BufferedImage oimage2 = ImageIO.read(file2);
ByteArrayOutputStream baos1=new ByteArrayOutputStream();
byte[] buf1 = new byte[1024];
try {
for (int readNum; (readNum = fis1.read(buf1)) != -1;) {
baos1.write(buf1, 0, readNum);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
ByteArrayOutputStream baos2=new ByteArrayOutputStream();
byte[] buf2 = new byte[1024];
try {
for (int readNum; (readNum = fis2.read(buf1)) != -1;) {
baos2.write(buf2, 0, readNum);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
final byte[] imageInByte1 = baos1.toByteArray();
final int size1 = imageInByte1.length;
final byte[] imageInByte2 = baos2.toByteArray();
final int size2 = imageInByte2.length;
int width1 = oimage1.getWidth();
int height1 = oimage1.getHeight();
int pixel1 = 0;
int red1,green1,blue1;
int width2 = oimage2.getWidth();
int height2 = oimage2.getHeight();
int pixel2=0,red2,green2,blue2;
final BufferedImage newimg1 = new BufferedImage(width1, height1, BufferedImage.TYPE_INT_ARGB);
final BufferedImage newimg2 = new BufferedImage(width2, height2, BufferedImage.TYPE_INT_ARGB);
for (int i = 0; i < width1; i++)
for (int j = 0; j < height1; j++) {
//scan through each pixel
pixel1 = oimage1.getRGB(i, j);
pixel2 = oimage2.getRGB(i, j);
//for red
String redpix1=Integer.toBinaryString(pixel1);
String binaryred1 = redpix1.substring(20,23);
String redpix2=Integer.toBinaryString(pixel2);
String binaryred2=redpix2.substring(20,23);
String newred= binaryred1 + binaryred2;
//for green
String greenpix1=Integer.toBinaryString(pixel1);
String binarygreen1=greenpix1.substring(12,15);
String greenpix2=Integer.toBinaryString(pixel2);
String binarygreen2=greenpix2.substring(12,15);
String newgreen= binarygreen1 + binarygreen2;
//for blue
String bluepix1=Integer.toBinaryString(pixel1);
String binaryblue1=bluepix1.substring(4,7);
String bluepix2=Integer.toBinaryString(pixel2);
String binaryblue2=bluepix2.substring(4,7);
String newblue= binaryblue1 + binaryblue2;
//combining the new values
String spixel=newred +newgreen + newblue;
int newpixel = Integer.parseInt(spixel);
newimg2.setRGB(i,j,newpixel);
}
JFrame f =new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JLabel(new ImageIcon(newimg2)));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
The size of 1.jpg is greater than size of 2.jpg.
Can this code be modified to get output? or is any another easy way to embed the image?
The error message isn’t very explanatory. The NumberFormatExceptiondocumentation isn’t either in this case. It says:
Thrown to indicate that the application has attempted to convert a
string to one of the numeric types, but that the string does not have
the appropriate format.
What happens is an int overflow. The largest int you can have is 2 147 483 647 (10 digits), so 10010101101111111 (17 digits after I removed the leading 0) is way too large. This problem shows as a NumberFormatException.
If you intended that to be a binary number, use Integer.parseInt(spixel, 2) to indicate radix 2 (that is, binary). Then you should be able to parse it since up to 31 binary digits fit in an ìnt (not 32 because it’s signed, so there’s a sign bit).
There is a similar question to this one: What is a NumberFormatException and how can I fix it? However, while the accepted answer to that one does mention overflow (pretty deep down in the answer), it doesn’t cover trying to parse a string with the wrong radix. Still you may want to read through the question and answers and learn.
I need to paste 3 pictures in single slide using Apache POI XSLF. However I could able to add only one picture in a slide. Also I could not find any ways to specify the size and orientation the picture should be.
Tried the following code
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide();
XSLFGroupShape group1 = slide.createGroup();
byte buf[] = new byte[1024];
for (int i = 1; i <= 2; i++) {
byte[] pictureData = IOUtils.toByteArray(new FileInputStream(
"C:\\Users\\Ashok\\Pictures\\" + i + ".png"));
int elementIndex = ppt.addPicture(pictureData,
XSLFPictureData.PICTURE_TYPE_PNG);
XSLFPictureShape picture = slide.createPicture(elementIndex);
List<XSLFPictureData> allPictures = ppt.getAllPictures();
System.out.println(allPictures.size());
}
FileOutputStream fos = new FileOutputStream("C:\\test2.pptx");
ppt.write(fos);
fos.flush();
fos.close();
The above code contains only the last image.
You nead to set Anchor to your pictures
for (int i = 1; i <= 2; i++) {
byte[] pictureData = IOUtils.toByteArray(new FileInputStream(
"C:\\Users\\Ashok\\Pictures\\" + i + ".png"));
int elementIndex = ppt.addPicture(pictureData,
XSLFPictureData.PICTURE_TYPE_PNG);
XSLFPictureShape picture = slide.createPicture(elementIndex);
// Set picture position and size
picture.setAnchor(new Rectangle(positionX, positionY, width, height));
List<XSLFPictureData> allPictures = ppt.getAllPictures();
System.out.println(allPictures.size());
}
I have a 2D array of image data in which I did some manipulations, but image is not getting saved on path specified i.e. Environment.getExternalStorageDirectory().getPath()+File.separator+"output.png".
I did the same code for Desktop application it is working fine in core Java. I have used BufferedImage to save 2D array of image data in a file. It is working totally fine, but I was wondering why this is not working in android. I did some research on this also, I got to know that Bitmap is the alternative for BufferedImage but the image is not getting written. Here I am posting my code please help me.
This is my java code:
BufferedImage theImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < imageHeight; ++y) {
for (int x = 0; x < imageWidth; ++x) {
theImage.setRGB(x, y, imgData[x][y]);
}
}
File outputfile = new File(filename);
try {
ImageIO.write(theImage, "png", outputfile);
} catch (IOException ex) {
}
Android code that I've tried:
int i =0;
for (int y = 0; y < imageHeight; ++y) {
for (int x = 0; x < imageWidth; ++x) {
values[i] = (byte) imgData[x][y];
i++;
}
}
try {
Bitmap bmp = BitmapFactory.decodeByteArray(values, 0, values.length);
OutputStream fos=new FileOutputStream(filename);
fos.write(values);
fos.close();
fos.flush();
res = true;
}catch (java.io.IOException e) {
e.printStackTrace();
}
Have you tried to Compress Before Writing Stream ??
insert this before stream write :
bmp.compress(Bitmap.CompressFormat.PNG, 90, fos);
Or: you can Use this Method:
private void createDirectoryAndSaveFile(Bitmap imageToSave, String fileName) {
File direct = new File(Environment.getExternalStorageDirectory() + "/DirName");
if (!direct.exists()) {
File wallpaperDirectory = new File("/sdcard/DirName/");
wallpaperDirectory.mkdirs();
}
File file = new File(new File("/sdcard/DirName/"), fileName);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I was finally able to write the following code which takes a animated GIF and converts it to a png strip. however for some reason it loses the transparency from the original gif. Can someone advise how i can keep the transparency
public class Main {
public static void main(String[] args) throws IOException {
Object input = new File("C:\\Users\\drizzt\\Documents\\jax.gif");
// or Object input = new FileInputStream("animated.gif");
ImageInputStream stream = ImageIO.createImageInputStream(input);
Iterator readers = ImageIO.getImageReaders(stream);
if (!readers.hasNext())
throw new RuntimeException("no image reader found");
ImageReader reader = (ImageReader) readers.next();
reader.setInput(stream); // don't omit this line!
int n = reader.getNumImages(true); // don't use false!
int h = reader.getHeight(0);
int w = reader.getWidth(0);
BufferedImage img = new BufferedImage(w * n, h,
BufferedImage.TYPE_INT_RGB);
boolean[] imagedrawn;
imagedrawn = new boolean[n];
// big.drawImage(outputimage, w*i, 0, null);
System.out.println("numImages = " + n);
for (int i = 0; i < n; i++) {
BufferedImage image = reader.read(i);
System.out.println("image[" + i + "] = " + image);
// img = BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
// img.createGraphics()
imagedrawn[i] = img.createGraphics().drawImage(image, w * i, 0,
null);
}
try {
// retrieve image
// BufferedImage bi = getMyImage();
File outputfile = new File("c:\\saved.png");
ImageIO.write(img, "png", outputfile);
} catch (IOException e) {
}
stream.close();
}
}
Replace this:
BufferedImage img = new BufferedImage(w * n, h, BufferedImage.TYPE_INT_RGB);
with
BufferedImage img = new BufferedImage(w * n, h, BufferedImage.TYPE_INT_ARGB);
...and you'll have transparency.
Possibly better yet, is to do:
BufferedImage img = reader.getRawImageType(0).createBufferedImage(w * n, h);
Then you'll keep the exact image layout from the GIF, and possibly get a smaller output image (a minor detail here, is that getRawImageType may return null if there's no corresponding color space in Java, but this should probably never happen for a GIF).
Unrelated to the issue, but still good practice: Whenever you do img.createGraphics() you should also call dispose() on the Graphics2D when done painting. Move the createGraphics() outside the loop and dispose after the loop for better performance.
It's even possible to avoid the drawing altogether, and read the contents of each frame directly into img, by replacing your loop with something like this:
ImageReadParam param = reader.getDefaultReadParam();
param.setDestination(img);
for (int i = 0; i++; i < n) {
param.setDestinationOffset(new Point(w * i, 0);
reader.read(i, param);
}