Image input output in Java - java

In this code I have taken an image as input and output the same image. As far I know if two images are same then their PSNR value will be inf. So I calculate their PSNR value using MATLAB but it shows 48.05 that means those image are not same. But I read and write the same image, why this is happening. How can I fix it?
public class ImageProcessing {
BufferedImage image = null;
int width;
int height;
public ImageProcessing() {
// Input the image
try {
File input = new File("image0.jpg");
image = ImageIO.read(input);
width = image.getWidth();
height = image.getHeight();
/*int count = 0;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
count++;
Color c = new Color(image.getRGB(j, i));
System.out.println("S.No: " + count + " Red: " + c.getRed() + " Green: " + c.getGreen() + " Blue: " + c.getBlue());
}
}*/
} catch (Exception e) {
System.out.println("Error: " + e);
}
// Output the image
try {
File input = new File("image1.jpg");
ImageIO.write(image, "jpg", input);
System.out.println("Writing complete.");
} catch (Exception e) {
System.out.println("Error: " + e);
}
}
public static void main(String[] args) {
// TODO code application logic here
System.out.println("System Start");
ImageProcessing obj = new ImageProcessing();
}
}

JPG is a lossy format, You will lose information reading it in and writing it out each time you save it.
Perhaps try using a non-lossy format such as PNG or GIF.

Right, to go off of Salmans comment, with lossless compression, every bit of data originally in the file remains after its uncompressed. This is generally used for txt documents or spreadsheet files where information can be lost such as financial data. PNG or GIF use lossless compression.
What would be the advantage of using loss compression? It makes the file smaller by removing redundant information. Typically the user doesn't notice it and is used in sound and video. JPEG uses lossy compression and usually the creator can decide how much loss to introduce to trade-off between file size and image quality.
Drawn mostly from: http://whatis.techtarget.com/definition/lossless-and-lossy-compression

Related

gray-scale image to matrix and matrix to gray-scale image

I am trying to get 2D matrix from gray-scale image and modify it, then return back to the gray-scale image.
But when try to convert the image to a matrix, the pixels return with black values.
How can I find a solution for this problem?
You can find the images below the code
Java code:
public class MyImageProcessing {
private SampleModel sampleModel;
public int[][] compute(File file)
{
try
{
BufferedImage img= ImageIO.read(file);
Raster raster=img.getData();
sampleModel = raster.getSampleModel();
int w=raster.getWidth(),h=raster.getHeight();
int pixels[][]=new int[w][h];
for (int x=0;x<w;x++)
{
for(int y=0;y<h;y++)
{
pixels[x][y]=raster.getSample(x,y,0);
}
}
return pixels;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
public void getImage(int pixels[][])
{
int w=pixels.length;
int h=pixels[0].length;
WritableRaster raster= Raster.createWritableRaster(sampleModel, new Point(0,0));
for(int i=0;i<w;i++)
{
for(int j=0;j<h;j++)
{
raster.setSample(i,j,0,pixels[i][j]);
}
}
BufferedImage image=new BufferedImage(w,h,BufferedImage.TYPE_BYTE_GRAY);
image.setData(raster);
File output=new File("C:\\Users\\salam\\Pictures\\3.png");
try {
ImageIO.write(image,"png",output);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Original image:
Image retrieved from matrix:
Try this code out.
If it is not what you need then perhaps what you could take away from my post is that code should always be neat, readable, properly indented, and commented, all of which adds to the understandability of the program.
Note: Your image returns practically the same black and white image when converted to grayscale, because your image is black and white much like a binary image.
I can also suggest OpenCV (https://opencv.org/) which is under a BSD licence, it's simple, powerful, and available for Java - although I remember it being a PITA when installing it on Ubuntu 16.04.
import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
/**
* This class converts images to grayscale color.
*/
public class GrayscaleConverter {
/**
* Creates a new grayscaled BufferedImage object from the given source image
* by averaging each pixels RGB value.
*
* #param inputImageAbsPath the absolute path of the image file, including its name and extension.
* #return a BufferedImage object.
*/
private BufferedImage compute(String inputImageAbsPath) {
System.out.println("... Converting source image to gray scale.");
BufferedImage img = null; // image file
// Read the source image or throw an exception
try {
img = ImageIO.read(new File(inputImageAbsPath));
} catch(Exception e) {
e.printStackTrace();
}
// Get the image width and height dimensions
int width = img.getWidth();
int height = img.getHeight();
// Convert to grayscale by looping over pixels, beginning at top-most left coordinate (0,0)
for (int y = 0; y < height; y++) { // y = rows
for (int x = 0; x < width; x++) { // x = columns
// Get the pixel value at this (x,y) coordinate
int p = img.getRGB(x,y);
// Extract the alpha, R, G, B values from pixel p
int a = (p>>24) & 0xff; // Shift bits and unsign
int r = (p>>16) & 0xff;
int g = (p>>8) & 0xff;
int b = p & 0xff;
// Calculate average color (grayscale it)
int avg = (r+g+b)/3;
// Replace RGB value with avg
p = (a<<24) | (avg<<16) | (avg<<8) | avg;
img.setRGB(x, y, p);
}
}
return img;
}
/**
* Saves the converted grayscale image. This method builds the save path from the provided file name,
* file extension, and absolute path of the folder that you want to save the image in.
*
* #param path the absolute path of the folder that you would like to save the image inside.
* #param imageName the name you would like to save the image with.
* #param imageFileType the image file extension, without the dot (.) preceding the image file type.
* #param image the BufferedImage object returned from the compute method.
*/
private void saveImage(String path, String imageName, String imageFileType, BufferedImage image) {
// Save or throw exception
try {
System.out.println("... Saving grayscale image to "
+ path.concat("\\").concat(imageName).concat(".").concat(imageFileType)); // save path displayed to user
ImageIO.write(image,
imageFileType,
new File(path.concat("\\").concat(imageName).concat(".").concat(imageFileType)));
} catch(Exception e) {
e.printStackTrace();
}
System.out.println("... Image saved.");
}
// Driver
public static void main(String args[]) throws IOException {
/*
* Tested for .png and .jpg files. Both worked successfully.
*/
// Test
System.out.println("Testing GrayscaleConverter.\n");
String input = "*source images absolute file path including name and extension*";
String outputPath = "*absolute path to folder where you will save grayscale image in*";
String outputFileName = "*save image with this name*";
String outputFileType = "*save image with this file extension (no dot (.) e.g. png or jpg)*";
GrayscaleConverter gsc = new GrayscaleConverter();
BufferedImage convertedImage = gsc.compute(input);
gsc.saveImage(outputPath, outputFileName, outputFileType, convertedImage );
System.out.println("\nTest complete.");
}
}
Your supplied input image:
Your output image:
Another sample input image:
Another sample output image:
I tested my program with both .png and .jpg image files and it worked. Good luck.

PDFBox PDFMergerUtility unstable on JavaFX application

My JavaFX application was downloading PDFs from the server, rotate to portrait if the PDF is landscape, and then merge all the PDF files into one single PDF file to print it out.
Everything went fine except the program will randomly stuck at outputting the merged PDF or adding one of the PDF files to PDFMergerUtility(which I am using PDFBox 2.0.11 and tried 2.0.9 also). Because my application requires a ProgressBar and TextArea to show the current action or status, I used a Task in my controller page. When the program hangs, it didn't enter any exception or print any message but completely stops the background action. I have tried small amount of files (<50 files) and large file tests (>1000), but they all have the same results of absolutely normal or randomly hangs.
Below are the code of my controller program:
public class ReadDataPageController implements Initializable {
public long startTime;
public long stopTime;
#FXML
private Button btnNext, btnCancel, btnPrevious;
#FXML
private Label infoLabel, time, total;
#FXML
private ProgressBar progBar;
#FXML
private TextArea textArea;
public Task<String> dlTask() {
return new Task<String>() {
#Override
protected String call() throws Exception {
DownloadUtil dlutil = new DownloadUtil();
StringBuilder textStr = new StringBuilder();
List<String> dlList = mainApp.DL_LIST;
// Download PDF files from FTP
super.updateValue(textStr.append("Preparing files for download...\n").toString());
for (int count = 0; count < dlList.size(); count++) {
String PDFLink = dlList.get(count).getPDFLink();
super.updateTitle("Downloading file" + PDFLink + " ...");
super.updateValue(textStr.append("Got " + PDFLink + "\n").toString());
try {
dlutil.exec(PDFLink);
// downloaded location will be stored inside List DownloadUtil.pdfList
} catch (IndexOutOfBoundsException ex) {
super.updateValue(textStr.append("Link not found for " + PDFLink + "\n").toString());
} catch (Exception ex) {
super.updateValue(textStr.append("Error while downloading " + PDFLink + " :" + ex.getMessage() + "\n").toString());
}
super.updateProgress(count + 1, dlList.size() * 3);
}
super.updateProgress(dlList.size(), dlList.size() * 3);
super.updateTitle("Download action has finished.");
super.updateValue(textStr.append("Download action has finished.\n").toString());
// Rotate downloaded PDFs
super.updateTitle("Preparing files for PDF rotation...");
super.updateValue(textStr.append("Preparing files for PDF rotation...\n").toString());
for (int i = 0; i < dlutil.pdfList.size(); i++) {
try {
String fileName = dlutil.pdfList.get(i);
rotatePDF(new File(fileName));
super.updateValue(textStr.append("Rotating PDF ("+(i+1)+" of "+dlutil.pdfList.size()+")...\n").toString());
} catch (Exception ex) {
super.updateValue(textStr.append("Error:" + ex.getMessage() + "...\n").toString());
ex.printStackTrace();
}
super.updateProgress(dlutil.pdfList.size() + i + 1, dlutil.pdfList.size() * 3);
}
if (PRINT_OPTION == PrintType.PRINT) {
// Merge downloaded PDFs
super.updateValue(textStr.append("Preparing files for PDF merging action...\n").toString());
PDFMergerUtility pdfutil = new PDFMergerUtility();
for (int i = 0; i < dlutil.pdfList.size(); i++) {
try {
String fileName = dlutil.pdfList.get(i);
pdfutil.addSource(fileName);
super.updateTitle("Adding files (" + (i + 1) + "/" + dlutil.pdfList.size() + ")");
} catch (Exception ex) {
super.updateValue(textStr.append("Error:" + ex.getMessage() + "...\n").toString());
ex.printStackTrace();
}
super.updateProgress(dlutil.pdfList.size()*2 + i + 1, dlutil.pdfList.size() * 3);
}
// Output merged pdf
try {
pdfutil.setDestinationFileName("../odt/merge.pdf");
pdfutil.mergeDocuments();
} catch (Exception ex) {
ex.printStackTrace();
}
super.updateTitle("Merged all PDFs.");
}
super.updateProgress(100, 100);
super.updateTitle("All action has been finished.");
super.updateValue(textStr.append("All action has been finished, press Next to choose your printing option.\n").toString());
return textStr.toString();
}
};
}
/**
* Rotates PDF images 90 degree if the PDF is portrait
* #param resource the PDF file path
* #throws InvalidPasswordException
* #throws IOException
*/
public void rotatePDF(File resource) throws InvalidPasswordException, IOException {
try {
PDDocument document = PDDocument.load(resource);
int pageCount = document.getNumberOfPages();
System.out.println("Reading file: "+resource+", total page="+pageCount);
for (int i = 0; i < pageCount; i++) {
PDPage page = document.getDocumentCatalog().getPages().get(i);
PDPageContentStream cs = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.PREPEND,
false, false);
Matrix matrix = Matrix.getRotateInstance(Math.toRadians(90), 0, 0);
cs.transform(matrix);
cs.close();
PDRectangle cropBox = page.getCropBox();
if (cropBox.getWidth() > cropBox.getHeight()) {
System.out.println("ROTATE "+i+"th");
Rectangle rectangle = cropBox.transform(matrix).getBounds();
PDRectangle newBox = new PDRectangle((float) rectangle.getX(), (float) rectangle.getY(),
(float) rectangle.getWidth(), (float) rectangle.getHeight());
page.setCropBox(newBox);
page.setMediaBox(newBox);
document.save(resource);
}
}
document.close();
} catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
}
}
Is there any reason that may cause the PDFMergerUtility unstable, maybe because I used a Task outside or because I missed something crucial?
Bingo! The exception was OutOfMemoryError, and Task from JavaFX made it silence.
I added the following code while initiating the task and it will handle the exceptions:
task.setOnFailed(new EventHandler<WorkerStateEvent>(){
#Override
public void handle(WorkerStateEvent event) {
Throwable th = task.getException();
System.out.println("Error on Task:"+th.getMessage());
th.printStackTrace();
}
});
To avoid OutOfMemoryError, I split the merging job into 100 pages per merging job, and save as multiple merged PDF files.

Locating a cell image

I have inserted an image in an Excel table successfully; but now I have a huge trouble, I want the images to be centered in a single cell, since when I export the file with the images, they seems to be inside one cell., but when I look closely the image is some millimeters our of the cell which makes difficult to work. The image doesn't recognize which cell it belong to. using the library of Apache POI.
I hope you can help me, thanks.
here I send you part of the code,
int posReporte = 1;
int posRow = 1;
for (List<Object> dr : datosReportes) {
Row filaReporte = hojaReporte.createRow(posReporte);
for (int a = 0; a < dr.size(); a++) {
Cell celdaD = filaReporte.createCell(angel);*
celdaD.setCellStyle(estiloDatos);
Object obj = dr.get(angel);
if (a == 0) {
hojaReporte.setColumnWidth(a, 180 * 38);
filaReporte.setHeight(Short.valueOf("1500"));
//Add image data to the book
try {
if (directorio("S:\\", dr.get(1) + "_mini")) {
InputStream is = new FileInputStream("S:\\" + dr.get(1) + "_mini.jpg");
byte[] bytes = IOUtils.toByteArray(is);
int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
is.close();
CreationHelper helper = wb.getCreationHelper();
Drawing drawing = hojaReporte.createDrawingPatriarch();
//Add image
ClientAnchor anchor = helper.createClientAnchor();
anchor.setCol1(o);
anchor.setRow1(posRow);
anchor.setAnchorType(o);
Picture pict = drawing.createPicture(anchor, pictureIdx);
pict.resize();
}
} catch (Exception e) {
continue;
}
}
}
}

How to record video from webcam in a lossless format?

I'm trying to write an application which can record video in a lossless format. For this purpose I use Webcam-Capture and Xuggler libraries. Everything works but the outout video has the following artifacts:
And this is observed not at all frames, nearly 1 of 5 ones. My code:
#FXML
public void record() {
File file = new File("output.wmv");
IMediaWriter writer = ToolFactory.makeWriter(file.getName());
Dimension size = WebcamResolution.VGA.getSize();
writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_RAWVIDEO, size.width, size.height);
Webcam webcam = Webcam.getDefault();
webcam.setViewSize(size);
webcam.open(true);
long start = System.currentTimeMillis();
for (int i = 0; i < 50; i++) {
System.out.println("Capture frame " + i);
BufferedImage image = ConverterFactory.convertToType(webcam.getImage(), BufferedImage.TYPE_3BYTE_BGR);
IConverter converter = ConverterFactory.createConverter(image, IPixelFormat.Type.YUV420P);
IVideoPicture frame = converter.toPicture(image, (System.currentTimeMillis() - start) * 1000);
frame.setKeyFrame(i == 0);
frame.setQuality(100);
writer.encodeVideo(0, frame);
// 10 FPS
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
writer.close();
System.out.println("Video recorded in file: " + file.getAbsolutePath());
}
What am I doing wrong?
Needs more information on your dependencies. Links maybe?

Loading an animated image to a BufferedImage array

I'm trying to implement animated textures into an OpenGL game seamlessly. I made a generic ImageDecoder class to translate any BufferedImage into a ByteBuffer. It works perfectly for now, though it doesn't load animated images.
I'm not trying to load an animated image as an ImageIcon. I need the BufferedImage to get an OpenGL-compliant ByteBuffer.
How can I load every frames as a BufferedImage array in an animated image ?
On a similar note, how can I get the animation rate / period ?
Does Java handle APNG ?
The following code is an adaption from my own implementation to accommodate the "into array" part.
The problem with gifs is: There are different disposal methods which have to be considered, if you want this to work with all of them. The code below tries to compensate for that. For example there is a special implementation for "doNotDispose" mode, which takes all frames from start to N and paints them on top of each other into a BufferedImage.
The advantage of this method over the one posted by chubbsondubs is that it does not have to wait for the gif animation delays, but can be done basically instantly.
BufferedImage[] array = null;
ImageInputStream imageInputStream = ImageIO.createImageInputStream(new ByteArrayInputStream(data)); // or any other source stream
Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(imageInputStream);
while (imageReaders.hasNext())
{
ImageReader reader = (ImageReader) imageReaders.next();
try
{
reader.setInput(imageInputStream);
frames = reader.getNumImages(true);
array = new BufferedImage[frames];
for (int frameId : frames)
{
int w = reader.getWidth(0);
int h = reader.getHeight(0);
int fw = reader.getWidth(frameId);
int fh = reader.getHeight(frameId);
if (h != fh || w != fw)
{
GifMeta gm = getGifMeta(reader.getImageMetadata(frameId));
// disposalMethodNames: "none", "doNotDispose","restoreToBackgroundColor","restoreToPrevious",
if ("doNotDispose".equals(gm.disposalMethod))
{
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) image.getGraphics();
for (int f = 0; f <= frameId; f++)
{
gm = getGifMeta(reader.getImageMetadata(f));
if ("doNotDispose".equals(gm.disposalMethod))
{
g.drawImage(reader.read(f), null, gm.imageLeftPosition, gm.imageTopPosition);
}
else
{
// XXX "Unimplemented disposalMethod (" + getName() + "): " + gm.disposalMethod);
}
}
g.dispose();
}
else
{
image = reader.read(frameId);
// XXX "Unimplemented disposalMethod (" + getName() + "): " + gm.disposalMethod;
}
}
else
{
image = reader.read(frameId);
}
if (image == null)
{
throw new NullPointerException();
}
array[frame] = image;
}
}
finally
{
reader.dispose();
}
}
return array;
private final static class GifMeta
{
String disposalMethod = "none";
int imageLeftPosition = 0;
int imageTopPosition = 0;
int delayTime = 0;
}
private GifMeta getGifMeta(IIOMetadata meta)
{
GifMeta gm = new GifMeta();
final IIOMetadataNode gifMeta = (IIOMetadataNode) meta.getAsTree("javax_imageio_gif_image_1.0");
NodeList childNodes = gifMeta.getChildNodes();
for (int i = 0; i < childNodes.getLength(); ++i)
{
IIOMetadataNode subnode = (IIOMetadataNode) childNodes.item(i);
if (subnode.getNodeName().equals("GraphicControlExtension"))
{
gm.disposalMethod = subnode.getAttribute("disposalMethod");
gm.delayTime = Integer.parseInt(subnode.getAttribute("delayTime"));
}
else if (subnode.getNodeName().equals("ImageDescriptor"))
{
gm.imageLeftPosition = Integer.parseInt(subnode.getAttribute("imageLeftPosition"));
gm.imageTopPosition = Integer.parseInt(subnode.getAttribute("imageTopPosition"));
}
}
return gm;
}
I don't think Java supports APNG by default, but you can use an 3rd party library to parse it:
http://code.google.com/p/javapng/source/browse/trunk/javapng2/src/apng/com/sixlegs/png/AnimatedPngImage.java?r=300
That might be your easiest method. As for getting the frames from an animated gif you have to register an ImageObserver:
new ImageIcon( url ).setImageObserver( new ImageObserver() {
public void imageUpdate( Image img, int infoFlags, int x, int y, int width, int height ) {
if( infoFlags & ImageObserver.FRAMEBITS == ImageObserver.FRAMEBITS ) {
// another frame was loaded do something with it.
}
}
});
This loads asynchronously on another thread so imageUpdate() won't be called immediately. But it will be called for each frame as it parses it.
http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/ImageObserver.html

Categories