Image resizing Java - java

I have a weird problem with resizing images and can't figure out what I'am doing wrong. I've read lots of posts wwhich basically have the same code as I:
(I use the java library Scalr)
File image = new File("myimage.png");
File smallImage = new File("myimage_s");
try {
BufferedImage bufimage = ImageIO.read(image);
BufferedImage bISmallImage = Scalr.resize(bufimage, 30); // after this line my dimensions in bISmallImage are correct!
ImageIO.write(bISmallImage, "png", smallImage); // but my smallImage has the same dimension as the original foto
} catch (Exception e) {}
Can someone tell me what I am doing wrong?

I do not see anything wrong with your code.
I pulled it into a quick test project in Eclipse targeting Java SE 7 and using imgscalr 4.2 on Windows 7 Pro 64-bit:
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import org.imgscalr.Scalr;
public class ScalrTest {
public static void main(String[] args) {
File image = new File("myimage.png");
File smallImage = new File("myimage_s.png"); // FORNOW: added the file extension just to check the result a bit more easily
// FORNOW: added print statements just to be doubly sure where we're reading from and writing to
System.out.println(image.getAbsolutePath());
System.out.println(smallImage.getAbsolutePath());
try {
BufferedImage bufimage = ImageIO.read(image);
BufferedImage bISmallImage = Scalr.resize(bufimage, 30); // after this line my dimensions in bISmallImage are correct!
ImageIO.write(bISmallImage, "png", smallImage); // but my smallImage has the same dimension as the original foto
} catch (Exception e) {
System.out.println(e.getMessage()); // FORNOW: added just to be sure
}
}
}
With the following myimage.png...
..., it produced the following myimage_s.png:
Maybe there is an environmental issue that's hamstringing your code, but possibilities that come to mind would come with a clear error.

Related

Java - Reading a frame in OpenCV

i have just started to learn openCV in java and i have setup my Eclipse IDE with all OpenCV java dependencies.
Now i have a task in hand to extract a single frame from a video file which i have recorded in .avi file format.
i searched from this link and used the code given there as below,
package vasanth;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;
public class Vasanth {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
VideoCapture camera = new VideoCapture("G:\\PICTURES\\roxtar vassy\\early days in APSCE.wmv");
/* if(!camera.isOpened()){
System.out.println("Error");
} */
Mat frame = new Mat();
while(true){
System.out.println("Looping.. \n");
if (camera.read(frame)){
System.out.println("Frame Obtained");
System.out.println("Captured Frame Width " +
frame.width() + " Height " + frame.height());
Highgui.imwrite("camera.jpg", frame);
System.out.println("OK");
break;
}
}
}
}
when i execute this, the program is looping at inifinitely at this line
camera.read(frame)
i also tried running this code without he loop and was successfully in getting the camera.jpg file on my system but the file was corrupted.
I understand that this frame was not completely extracted with all the pixels and hence seems corrupted.
So the problem here is why does camera.read(frame) this always return false and the loop never breaks?
I have waited for more than 10 minutes.
All i want to do is extract one single frame and it is not happening with this method.
As per what i have searched on google i understant there is a tool called ffmpeg which takes a video file as input and give me frames.
But i want to achieve this functionality with my own java code running on Eclipse for starters.
There are couple of issues I faced while reproducing your issue, so let me guide you through them.
First of all, you use the old version of the framework. The current one is 3.2, so consider upgrading. I used the newest version.
You should not comment out the camera.isOpened() check since if the camera is not opened there is no sense to proceed. I assume, that your app couldn't pass that check, so you decided to skip that :) But in order to open the camera properly you should either do this or this. The first link worked for me (the only change is that for 3.2 version the path is \opencv\build\x64\vc14\bin and I had to reboot computer)
The code is pretty much the same as you have so far with only difference for the latest version:
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.videoio.VideoCapture;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.nio.file.Paths;
public class Vasanth {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
String filePath = "G:\\PICTURES\\roxtar vassy\\early days in APSCE.wmv";
if (!Paths.get(filePath).toFile().exists()){
System.out.println("File " + filePath + " does not exist!");
return;
}
VideoCapture camera = new VideoCapture(filePath);
if (!camera.isOpened()) {
System.out.println("Error! Camera can't be opened!");
return;
}
Mat frame = new Mat();
while(true){
if (camera.read(frame)){
System.out.println("Frame Obtained");
System.out.println("Captured Frame Width " +
frame.width() + " Height " + frame.height());
Imgcodecs.imwrite("camera.jpg", frame);
System.out.println("OK");
break;
}
}
BufferedImage bufferedImage = matToBufferedImage(frame);
showWindow(bufferedImage);
camera.release();
}
private static BufferedImage matToBufferedImage(Mat frame) {
int type = 0;
if (frame.channels() == 1) {
type = BufferedImage.TYPE_BYTE_GRAY;
} else if (frame.channels() == 3) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
BufferedImage image = new BufferedImage(frame.width(), frame.height(), type);
WritableRaster raster = image.getRaster();
DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
byte[] data = dataBuffer.getData();
frame.get(0, 0, data);
return image;
}
private static void showWindow(BufferedImage img) {
JFrame frame = new JFrame();
frame.getContentPane().add(new JLabel(new ImageIcon(img)));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(img.getWidth(), img.getHeight() + 30);
frame.setTitle("Image captured");
frame.setVisible(true);
}
}
Note, that in order to demonstrate that this piece of code works I use simple Swing JFrame:
I was facing the same issue which is camera.isOpened() returning false.
This is how I resolved it.
String filePath = "C:\\Aslam_Face_Detection.mp4";
VideoCapture camera = new VideoCapture(filePath);
camera.open(filePath); // This is the line I added
camera.isOpened(); // returns true. worked.

How to convert an image from 8-Bit to RGB in ImageJ2 using Java

I'm trying to use ImageJ2 directly from Java to create a binarised image coming from an input image.
A somewhat working version of my code looks like this:
final File file = new File("input.png");
try {
DefaultDataTypeService dataTypeService = new DefaultDataTypeService();
Dataset dataset = imageJ.dataset().open(file.getAbsolutePath());
Img inputImg = dataset.getImgPlus();
PluginInfo pluginInfo = imageJ.plugin().getPlugin(Binarize.class);
Binarize binarizeOp = (Binarize) pluginInfo.createInstance();
binarizeOp.setContext(imageJ.getContext());
binarizeOp.setChangeInput(true);
binarizeOp.setFillMaskBackground(true);
binarizeOp.setFillMaskForeground(true);
binarizeOp.setInputData(dataset);
binarizeOp.setInputMask(null);
binarizeOp.setMaskColor(Binarize.WHITE);
binarizeOp.setMaskPixels(Binarize.INSIDE);
binarizeOp.setThresholdEachPlane(false);
binarizeOp.setDefaultThresholdMethod();
binarizeOp.run();
dataset.rgbChange();
DefaultDatasetService defaultDatasetService = new DefaultDatasetService();
Img outputImg = dataset.getImgPlus();
outputImg = outputImg.factory().imgFactory(new UnsignedByteType()).create(outputImg,new UnsignedByteType());
Dataset outputDataset = defaultDatasetService.create(outputImg);
imageJ.dataset().save(outputDataset,"input_binary.png");
} catch (IOException e) {
e.printStackTrace();
} catch (InstantiableException e) {
e.printStackTrace();
} catch (IncompatibleTypeException e) {
e.printStackTrace();
}
Running this code I have the problem that "input_binary.png" will be completely black, a behaviour I can reproduce using the ImageJ client application.
What I need to do in the client is to change the image type from "8-bit Color" to "RGB-Color". But I can not figure out how to reproduce that in Java using the current version of the net.imagej library.
I know that it would be possible using the 1.x library but I would like to to it using the 2.x.
Any help would be greatly appreciated.
You're getting black images because of this:
outputImg = outputImg.factory().imgFactory(new UnsignedByteType()).create(outputImg,new UnsignedByteType());
Which is just copying the dimensionality of your source image, not its values.
A few other key points:
It's best practice to have your Contextual objects (e.g. Services) derived from the Context instead of manually constructed.
The Binarize command has a Dataset output so it's not necessary to go Dataset > ImgPlus > Dataset
If you do want to write the dataset out you need to convert from the BitType output by Binarize to one that's supported.
See below for an example of running Binarize, getting the output, converting it and writing it out. Hope that helps!
public static void main(String... args) {
final File file = new File("inpath.png");
final File out = new File("outpath.png");
// This is just sugar for the point of illustration.
// The purpose here is just to have access to a Context
ImageJ imagej = new ImageJ();
// Cache the context for future use.
Context context = imagej.getContext();
try {
// Use the context to get the services we want to ensure they are all
// properly initialized.
// If this was a Command these could all be #Parameters to be populated
// automatically.
DatasetService datasetService = context.getService(DatasetService.class);
CommandService commandService = context.getService(CommandService.class);
DatasetIOService datasetIOService =
context.getService(DatasetIOService.class);
Dataset input = datasetIOService.open(file.getAbsolutePath());
// Start the command
Future<CommandModule> future =
commandService.run(Binarize.class, true, "inputData", input);
// Get the command output
Dataset binarized = (Dataset) future.get().getOutput("outputMask");
// The output type is a binary image which, at the moment, needs to be
// explicitly converted to something that can be written out.
// Adapted from:
// http://fiji.sc/ImgLib2_Examples#Example_2c_-_Generic_copying_of_image_data
Img inputImg = input.getImgPlus().getImg();
Img outputImg = binarized.getImgPlus().getImg();
Img typedImg =
inputImg.factory().create(inputImg, inputImg.firstElement());
scale(outputImg, typedImg);
Dataset output = datasetService.create(typedImg);
// Save the output dataset
datasetIOService.save(output, out.getAbsolutePath());
}
catch (IOException exc) {
exc.printStackTrace();
}
catch (InterruptedException exc) {
exc.printStackTrace();
}
catch (ExecutionException exc) {
exc.printStackTrace();
}
finally {
// Dispose of the context to shut down
context.dispose();
}
}
public static <T extends IntegerType<T>> void scale(
final RandomAccessible<BitType> source, final IterableInterval<T> target)
{
// create a cursor that automatically localizes itself on every move
Cursor<T> targetCursor = target.localizingCursor();
RandomAccess<BitType> sourceRandomAccess = source.randomAccess();
// iterate over the input cursor
while (targetCursor.hasNext()) {\
// move input cursor forward
targetCursor.fwd();
// set the output cursor to the position of the input cursor
sourceRandomAccess.setPosition(targetCursor);
// set the value of this pixel of the output image
BitType b = sourceRandomAccess.get();
if (b.get()) {
targetCursor.get().setOne();
}
else {
targetCursor.get().setZero();
}
}
}

OpenCV in Java for Image Filtering

i have java codes from Tutorials Point. This code for Robinson filter.
package improctry2;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;
public class ImProcTry2 {
public static void main( String[] args )
{
try {
int kernelSize = 9;
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
Mat source = Highgui.imread("grayscale.jpg",
Highgui.CV_LOAD_IMAGE_GRAYSCALE);
Mat destination = new Mat(source.rows(),source.cols(),source.type());
Mat kernel = new Mat(kernelSize,kernelSize, CvType.CV_32F){
{
put(0,0,-1);
put(0,1,0);
put(0,2,1);
put(1,0-2);
put(1,1,0);
put(1,2,2);
put(2,0,-1);
put(2,1,0);
put(2,2,1);
}
};
Imgproc.filter2D(source, destination, -1, kernel);
Highgui.imwrite("output.jpg", destination);
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
This is is my image input, and this the output (i can't post the pictures because i'm new in stackoverflow).
As you can see, the image turn into black and nothing appears. I'm using Netbeans IDE 8.0 and i already put the OpenCV library in Netbeans. I also run another OpenCV Java codes and they work very well. And i also run this code in Eclipse but the result is same.
Anybody can help me?
Thank You
You create a 9x9 kernel matrix, but then fill only a 3x3 submatrix of it, leaving other elements unititialized. To fix it, just change:
int kernelSize = 9;
to:
int kernelSize = 3;
Your code actually works in the newest Opencv (3.0 beta), but those unititialized elements break it in older versions (I checked 2.4.10). To print elements of a matrix use:
System.out.println(kernel.dump());
PS.
Welcome to stackoverflow. :)

Read data from GUI

I have a general question :
If I got a GUI (e.g. metaTrader => online broker), is it possible to read data from this GUI using java?
My idea:
Using the java.awt.robot and do something like:
package java_robot;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
public class java_robot {
public static void main(String[] args) {
try {
// create class
Robot robot = new Robot();
// wait 1 sec
robot.delay(1000);
// move mouse to wanted area
robot.mouseMove(x, y);
}
// mark an area, copy it and save in file..
} catch (AWTException e) {
e.printStackTrace();
}
}
}
Is this idea good, or do you know other solutionĀ“s to read data from a GUI?
(working on mac)
You can use the Robot#createScreenCapture() method here.
Robot r = new Robot();
// Capture area
int width = ...
int height = ...
Rectangle area = new Rectangle(width, height);
BufferedImage image = r.createScreenCapture(area);
// Save to file
ImageIO.write(image, "png", new File("/screenshot.png"));
Alternatively, if metaTrader loads its data from internet, you can sniffe its traffic and determine how and where its data comes. Then you could try to mimic its internet calls and get the data yourself as long as it is not ciphered.
You could also build a proxy in Java and ask metaTrader to use this proxy. All data requested by metaTrader would go through your proxy. This can give you a chance to read the data... again as long as it is not ciphered.
The image below illustrates how things work. Alice plays the role of meaTrader. Bob is the source of data of metaTrader. Proxy is your Java app.
You can find a simple implementation of such a proxy here: http://www.java2s.com/Code/Java/Network-Protocol/Asimpleproxyserver.htm.
References:
Proxy server

Enlarging image using GD results in dismal quality compared to Scalr (JAVA)

I have been dealing with very small images and I have tried to discover the best way to increase them. I compared two different sources: imagecopyresampled (PHP: http://www.php.net/manual/en/function.imagecopyresampled.php) versus Scalr (JAVA: How to resize images in a directory?). I am including the codes that I am using below for the sake of completeness, but they are strongly based on other threads or sites referenced above. If someone thinks that I should remove, I will do that! In both sources it seems that the algorithm used to deal with the issue seems to be the same: Bicubic interpolation. However, in the case of the JAVA source, the quality of the resized image is MUCH MUCH better in my implementation (it is not even possible to compare). Am I doing something wrong when I am using the PHP source? If not, does anyone can explain me the difference between them?
JavaCode:
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import static org.imgscalr.Scalr.*;
public class App2 {
public static void main(String[] args) throws IOException {
for (File sourceImageFile : new File("imgs").listFiles()) {
if (sourceImageFile.getName().endsWith(".jpg"))
res(sourceImageFile.getAbsolutePath());
}
}
public static void res(String arg) throws IOException {
File sourceImageFile = new File(arg);
BufferedImage img = ImageIO.read(sourceImageFile);
BufferedImage thumbnail = resize(img, 500);
thumbnail.createGraphics().drawImage(thumbnail, 0, 0, null);
ImageIO.write(thumbnail, "jpg", new File("resized/" + sourceImageFile.getName()));
}
}
PHP code:
<?php
// The file
$filename = 'photos/thePhoto.jpg';
// Set a maximum height and width
$width = 250;
$height = 250;
// Content type
header('Content-Type: image/jpeg');
// Get new dimensions
list($width_orig, $height_orig) = getimagesize($filename);
$ratio_orig = $width_orig/$height_orig;
if ($width/$height > $ratio_orig) {
$width = $height*$ratio_orig;
} else {
$height = $width/$ratio_orig;
}
// Resample
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
// Output
imagejpeg($image_p, null, 100);
?>
Just to be clear, in the JAVA code, I have to keep the images in a folder. In the PHP code, I provide the name of the file. Off course, I compared exactly the same image. Furthermore, both codes are running without any kind of problem.
![PHP versus Java (in this order)]: http://www.facebook.com/media/set/?set=a.122440714606196.1073741825.100005208033163&type=1&l=55d93c4969

Categories

Resources