im currently trying to implement a webcam scanner. My current problem is that i can't capture a high quality image when using Java.
The camera i use has 8MP and produces great images when i use the Windows "Camera"-App. Sadly i can't replicate this quality with JavaCV.
This is the (important) code i'm using to capture an Image:
FrameGrabber grabber;
private Java2DFrameConverter frameConverter;
public JavaCVCamera(String imagePath, double rotation) {
this.frameConverter = new Java2DFrameConverter();
this.imagePath = imagePath;
this.rotation = rotation;
this.grabber = new OpenCVFrameGrabber(0);
this.grabber.setImageWidth(3264);
this.grabber.setImageHeight(2448);
try {
this.grabber.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void saveImageToFile(boolean applyUpscaling, boolean applyRotation) {
File folder = new File(imagePath);
if (!folder.exists()) {
folder.mkdirs();
}
try {
BufferedImage img = frameConverter.convert(grabber.grab());
if (applyUpscaling) {
img = Thumbnails.of(img).forceSize(3264, 2448).asBufferedImage();
}
if (applyRotation) {
img = rotateImageByDegrees(img, rotation);
}
File path = new File(imagePath + "/img_"
+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss")) + "." + "png");
ImageIO.write(img, "png", path);
LOGGER.info("Captured Image: {}", path.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
(Note: i dont use upscaling to make the images larger)
For your understanding, here's an example:
Captured with Windows Camera App
https://imgur.com/a/oOuMJdl
Captured with Java+JavaCV
https://imgur.com/a/DghFT8z
Is there some way to capture images with the same resolution and quality as the Windows Camera App?
Kind Regards,
QUE
A BufferedImage is very memory consuming in Java as it stores the image in a Bitmap like image format. Other image formats that use compression consume less memory. But how to use them with JavaCV?
First of all, check with a profiler app which code is responsible for the extensive memory consumption of your implementation. Hopefully the Frame stores the image data still in compressed form; and when executing the frameConverter.convert it consumes the high amount of memory. In this case, search for a solution that stores the image as a JPEG (or any other compressed data) in a byte[] - for displaying the image, you can draw the image directly e.g. to a Graphics2D element w/o converting it to a BufferedImage first. Use ToolkitImage therefore, which is able to draw a JPEG image from an InputStream image source. This can be a ByteArrayInputStream, if you were able to store your high-res image in a JPEG directly from the JavaCV.
Related
I am working on a project for my course and have been asked to show an associated image for products in a system, the user can add products, and he enters the name of the image file whilst doing so. the program then finds the image file and displays it with the product information.
I would like to add some additional code so that if there is no image file matching the string input that a standard image is shown. The code I have so far either shows the image file if it is found or does not show anything. can someone show me how to modify it so that it can show a standard image if no associated image file is found. the standard image is simply "no-image-found.jpg". Here is the code:
public void showImage(JLabel imageArea, String image){
BufferedImage img = null;
try {
img = (BufferedImage)ImageIO.read(new File(image));
Image actualimage = img.getScaledInstance(imageArea.getWidth(), imageArea.getHeight(), 0);
imageArea.setIcon(new ImageIcon(actualimage));
}
catch (IOException e) {
System.out.println(e.getMessage());
}
}
any help is very much appreciated, and my sincere apologies if this is a noob question, I am quite new to java.
In the catch, you could load the standard image and show it
Basically check for image existence assuming path is valid otherwise get the standard image. You can have something similar:
public void showImage(JLabel imageArea, String image)
{
BufferedImage img = null;
try
{
file = new File(image);
if (file.exists())
{
img = ImageIO.read(file);
}
else
{
file = new File(standardImagePath);
img = ImageIO.read(file);
}
Image actualimage = img.getScaledInstance(imageArea.getWidth(), imageArea.getHeight(), 0);
imageArea.setIcon(new ImageIcon(actualimage));
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
I'm trying to take a screenshot using a background service. This service is like a Facebook chathead, but I want it to take an screenshot when I do a click.
I've developed some code but it doesn't work. The last I've tried was:
private void takeScreenshot() {
Date now = new Date();
android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStorageDirectory().toString() + "/capture/" + now + ".jpg";
// create bitmap screen capture
Bitmap bitmap;
View v1 = chatHead.getRootView();
v1.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
OutputStream fout = null;
File imageFile = new File(mPath);
try {
fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fout);
fout.flush();
fout.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
But is taking an screenshot to my button not to the screen.
I know the problem is here:
View v1 = chatHead.getRootView();
But I don't know how to fix it. Can anyone help me?
I'm actually using Android Studio 2.2.2 and Android 4.0 or greater.
For Lollipop and above you can use the MediaProjection API of Google to take the screenshot but you need to ask for the permission from the user.
You can find the sample screen capture code using MediaProjection Here
For the devices less then Lollipop you need root permission for it.
To get a screenshot containing views not belonging to your app you'll need to use the MediaProjectionManager.
See How to take a screen shot with status bar contents in android application?
Use MediaProjectionManager#createScreenCaptureIntent given in the MediaProjection API of Android. What you are doing now is taking the chatHead's root view's information rather than information present on the complete screen of your device including the status bar at the top.
I wonder if anyone could help? I have been developing a java app which displays images from disk on a jframe.
Using netbeans I have created a java package called images within my project and stored the images in that package. First off is that the way I should do it If I want them to ship with the app?
I have the following function to read the image:
Image readImg(String file)
{
Image image = null;
try {
File imgFile = new File(file);
image = ImageIO.read(imgFile);
} catch (IOException e) {
// System.out.println("Can not Display Image");
e.printStackTrace();
}
if (image != null){
return image;
} else{
return null;
}
}
My problem comes that I cannot work out the relative filepath to pass to the function. I have got the image to display calling it like so:
Image headerImg = readImg("C:\\Users\\D#nb0y\\Documents\\NetBeansProjects\\GiftAidApp\\src\\images\\galogo.png");
Obviously this will completely fall apart if the app is run on any other device. Can anyone give me a heads up as to making this code portable?
thanks very much
Since it's a JFrame you're trying to add an image to, it might be better to use an ImageIcon instead of an Image.
Try this:
ImageIcon image = new ImageIcon("images/galogo.png");
JLabel imageLabel = new JLabel(image);
frame.add(imageLabel);
This should make the app portable as well if you include you images folder along with your project.
i want to convert a .webp image to .jpeg. I have used javax.imageio.ImageIO.
but # line no: 19 bImage = ImageIO.read(fis); returns a null for webp images.
Code is working fine if I try to convert .png ,.gif file format..
can any one help?
public static void imageIoWrite() {
BufferedImage bImage = null;
try {
File initialImage = new File("resources/1.webp");
FileInputStream fis = new FileInputStream(initialImage);
bImage = ImageIO.read(fis); //why it returns null?
if (bImage != null) {
ImageIO.write(bImage, "jpg",
new File("resources/NewImage1.jpg"));
System.out.println("Image file written successfully");
} else {
System.out.println("imag is empty");
}
} catch (IOException e) {
System.out.println("Exception occured :" + e.getMessage());
}
}
It seems that ImageIO is not able to read webp images. As you can read in the docs, the method read returns null in this case. I think that you have to use an additional library to read and write webp images.
BACKGROUND
Hey so I have a camera that I have implemented myself in code. This means I access and control the camera hardware and use it to save pictures. I can save the picture using the Camera.takePicture() function when the camera is running: running means Camera.startPreview();
PROBLEM
My problem is that I want to be able to save the image also when the camera image is frozen: frozen is when Camera.stopPreview(); is called.When frozen I can see the image in my layout but how do I access it? Where is the image saved so that I might be able to modify it later?
Thanks in advance!
------------------Update 1
jpeg bla;
public class jpeg implements PictureCallback{
public void onPictureTaken(byte[] data, Camera camera) {
g_data = data;
}
}
This is part of my code. Here I am trying to write the data that would originally be saved to a global variable. However the value of g_data remains null and I am unable to set a breakpoint inside the onPictureTaken() call back function.
------------------Update 2
FileOutputStream outStream = null;
try {
// generate the folder
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "MirrorMirror");
if( !imagesFolder.exists() ) {
imagesFolder.mkdirs();
}
// generate new image name
SimpleDateFormat formatter = new SimpleDateFormat("HH_mm_ss");
Date now = new Date();
String fileName = "image_" + formatter.format(now) + ".jpg";
// create outstream and write data
File image = new File(imagesFolder, fileName);
outStream = new FileOutputStream(image);
outStream.write(data);
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) { // <10>
//Toast.makeText(ctx, "Exception #2", Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {}
I used this code previously to save the file from the camera onPictureTaken() function. The key here is the byte[] data which I need to save and save later. However like I said I just get a null when I check it in the debugger.
Camera.takePicture never looks at the view you specified as previewDisplay. Actually, it isn't an ImageView, but a SurfaceView, and there are no API to read pixels from it.
You can call takePicture() preemptively just before you stopPreview(). Later, if you find out that you don't need the picture, just discard it.
Ok so the exact way to do this is to take the picture just before stopPreview() and save it to a temporary file. Actually with this implementation you never call stopPreview()(otherwise it will crash) since the takePicture() function stops the preview automatically.
try {
File temp = File.createTempFile("temp", ".jpg");
} catch (IOException e) {
e.printStackTrace();
}
Now that we have the temporary file saved we will access it later and move it to our new desired file location.
How to copy file.
temp.deleteOnExit();
be sure to call deleteonExit() so that Android deletes the file after the app is closed(if so desired).