I've managed to make a LineFollower program; added the feature of "memorizing" the path the robot just followed.
The next step is to draw that path and save the image file in the brick and read it in the PC with the NxjBrowse.
I thought I'd try using the classic java method, with BufferedImage and saving with ImageIO, but it didn't work and it kept giving me Java Heap Space:
My previous question
After that, I've made some research and found that there's a class called javax.microedition.lcdui.Image, so I've created an Image object and used GetGraphics and tried to draw on it; and save it using FileOutputStream, here's my code:
Image img = Image.createImage(300, 300);
Graphics g = img.getGraphics();
g.drawLine(0, 0, 100, 200);
File monFichier = new File("Image2.png");
FileOutputStream fOut = null;
try {
fOut = new FileOutputStream(monFichier);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] b = img.getData();
try {
fOut.write(b);
fOut.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The problem is that it writes on the file which is not recognized as an image, when I connect to my PC; I can't open the created file (checked the size, not empty).
I don't know if the saving is wrong or the method i'm using to draw is wrong.
Short version of the question: How to draw lines with Lejos and save the resultat as an image file?
Thank you.
UPDATE:
I used an ImageOutputStream instead of FileOutputStream; and now it's giving me "Java Heap Space" error; after it got stuck in "linking" for a while.
Java Heap Space
Java.lang.OutOfMemoryError
Image.getData() is an access to the underlying DataBuffer and not a valid PNG or BMP image.
Try ImageIO.write(img, "png", outputfile).
Related
I need to decode an .png image to use it as a base to create some Rects and to use the image itself as a background for my application, but the try-catch keeps throwing me a Null Pointer Exception, this is the code:
try {
InputStream is = ParamsSingleton.assetManager.open("background.png");
figure = BitmapFactory.decodeStream(is);
height = figure.getHeight();
width = figure.getWidth();
src = new Rect(0, 0, width, height);
first = new Rect();
} catch (IOException e) {
Log.d(TAG, "Image decode fail!");
}
I've tried some logs and the try-catch break right on the InputStream line and prints the 'Log.d' in catch block, I checked the file name and it is alright.
You can directly use getAssets.open method inside decodeStream .
figure = BitmapFactory.decodeStream(getAssets.open("background.png"));
I have a problem with Java application, particular in loading a image from a location in my computer.
Following this post I used a BufferedImage and a InputFileStream to load an image on my computer. First, I put the image (pic2.jpg) into the source code and that is working. However, if I put the image to another place (let's say C:\\ImageTest\pic2.jpg), Java IDE show me an IllegalArgumentException
return ImageIO.read(in);
here is the code:
public class MiddlePanel extends JPanel {
private BufferedImage img;
public MiddlePanel(int width) {
//img = getImage("pic2.jpg");
img = getImage("C:\\ImageTest\\pic2.jpg");
this.setPreferredSize(new Dimension(800,460));
}
public void paintComponent(Graphics g) {
// ...
}
private BufferedImage getImage(String filename) {
// This time, you can use an InputStream to load
try {
// Grab the InputStream for the image.
InputStream in = getClass().getResourceAsStream(filename);
// Then read it.
return ImageIO.read(in);
} catch (IOException e) {
System.out.println("The image was not loaded.");
//System.exit(1);
}
return null;
}
}
To read an .jpg file from non-relative path you could use this:
BufferedImage img = null;
try
{
img = ImageIO.read(new File("C:/ImageTest/pic2.jpg")); // eventually C:\\ImageTest\\pic2.jpg
}
catch (IOException e)
{
e.printStackTrace();
}
I do not have any Java environment at the moment, so hope it works and is written correctly.
getResource & getResourceAsStream do not work with file paths, but paths relative the code base. If the code base is C: then a relative path that would locate the resource is /ImageTest/pic2.jpg.
..difference between load file by FileInputStream and getResourceAsStream?
One major difference is that the getResource.. will work with a resource inside a Jar, which is no longer a File. Therefore FileInputStream cannot be used to access such a resource.
You cannot use Class#getResource(String) or Class#getResourceAsStream(String) in this case. The rules for searching resources associated with a given class are implemented by the defining class loader of the class. This method delegates to this object's class loader. If this object was loaded by the bootstrap class loader, the method delegates to ClassLoader.getSystemResourceAsStream(java.lang.String).
Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:
If the name begins with a / (\u002f), then the absolute name of the resource is the portion of the name following the /.
Otherwise, the absolute name is of the following form:
modified_package_name/name
Where the modified_package_name is the package name of this object with / substituted for . (\u002e).
Generally, it is not a good thing to hard code the system location of your resources in your code. The neat and clean way is to put your resources in your classpath and access them. Hope this clarifies why it's not working
//This code snippet read an image from location on the computer and writes it to a different location on the disk
try {
byte[] imageInByte;
BufferedImage imageOnDisk = ImageIO.read(new File("C:\\ImageTest\\pic2.jpg"));
//Create a ByteArrayOutputStrea object to write image to
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//Write the image to the OutputStream
ImageIO.write(imageOnDisk, "jpg", baos);
baos.flush();
//Initialise the byte array object with the image that was written to the OutputStream
imageInByte = baos.toByteArray();
baos.close();
// convert byte array back to BufferedImage
InputStream in = new ByteArrayInputStream(imageInByte);
BufferedImage bImageFromConvert = ImageIO.read(in);
//write the image to a new location with a different file name(optionally)
ImageIO.write(bImageFromConvert, "jpg", new File(
"c:\\index.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
To find the image Width, height and size
BufferedImage image = null;
int imageWidth = -1;
int imageHeight = -1;
int fileSize = -1;
try {
File imageFile = new File(imagePath);
int fileSize = (int) imageFile.length();
image = ImageIO.read(imageFile); // Reading the Image from the file system
imageWidth = image.getWidth();
imageHeight = image.getHeight();
} catch (IOException e) {
e.printStackTrace();
}
I am a java programmer,I am trying to use the screen which are open and take a screen shot and compare it with an other picture and see how many of that object is on my screen. I tried to look for examples in java, but they were all in c++ and i couldn't convert them. I know my problem is in the first line, since CascadeClassifier wants a .xml file not a .png. Can someone help me with this, all I want is a program in java that do the same as this example but using the screen shot, or using screen-capture.
CascadeClassifier balDec = new CascadeClassifier("img/ball.png");
BufferedImage screenShot = r.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
try {
ImageIO.write(screenShot, "png", new File("screenShot"+i+".png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Mat screen =Highgui.imread("screenShot0.png");
MatOfRect balls = new MatOfRect();
balDec.detectMultiScale(screen, balls);
I have a layout in an Android activity, I convert it as an image and then share it on different social networks.
The things is that the quality is not good at all, I have artifacts on the image, and the quality depend of the size of the screen.
Is there any way to improve the quality ? I can't store the complete layout image as a static image in the application directory, I need it to be generated on the go.
Here is code I use to transform the layout into a PNG.
Bitmap bitmap = null;
try {
bitmap = Bitmap.createBitmap(dashboardView.getWidth(),
dashboardView.getHeight(), Bitmap.Config.ARGB_4444);
dashboardView.draw(new Canvas(bitmap));
} catch (Exception e) {
// Logger.e(e.toString());
}
FileOutputStream fileOutputStream = null;
File path = Environment
.getExternalStorageDirectory();
File file = new File(path, "wayzupDashboard" + ".png");
try {
fileOutputStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
bitmap.compress(CompressFormat.PNG, 100, bos);
try {
bos.flush();
bos.close();
fileOutputStream.flush();
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
Edit: My bad, I left ARGB_4444, the fact is I made a lot of test before posting the question on SO, I just forgot to put ARGB_8888 in. Still the image quality is bad on Android phone with tiny screen. If only I could tell to always use HDPI drawable while capturing the layout.
ARGB_4444 means that you have only 4 bits per channel (a really poor quality).
Use ARGB_8888.
you are using Bitmap.Config.ARGB_4444. I suggest you to use ARGB_8888, like Google tells us
ARGB_4444 This field was deprecated in API level . Because of the
poor quality of this configuration, it is advised to use ARGB_8888
instead.
I've to make a parallel image processing script in java, the idea is to divide the images into tiles of any size, process them, and reassemble the final image.
For now i've created a function:
public static BufferedImage readImg (String path, int startx, int starty, int w, int h)
that returns the region of an image as BufferedImage, then i'll process it and i want to place that region in the correct position of the final image.
So i've tried to make a function writeImg that uses replacePixels method to write just in the correct position without loading the whole image into memory:
public static void writeImg (String path, int startx, int starty, BufferedImage image){
File output = new File(path);
ImageOutputStream ios = null;
try {
ios = ImageIO.createImageOutputStream(output);
} catch (IOException e){
e.printStackTrace();
}
Iterator iter = ImageIO.getImageWritersByFormatName("JPEG");
ImageWriter writer = (ImageWriter)iter.next();
writer.setOutput(ios);
try{
if(writer.canReplacePixels(0)){
System.out.println("True");
}else{
System.out.println("False");
}
}catch (IOException e) {
e.printStackTrace();
}
ImageWriteParam param = writer.getDefaultWriteParam();
Point destinationOffset = new Point(startx,starty);
param.setDestinationOffset(destinationOffset);
try {
writer.replacePixels(image, param);
} catch (IOException e) {
e.printStackTrace();
}
}
The problem is that canReplacePixels is always set as false, and i've no idea what should i use to do that.
The images can be very big so it's impossible to load the whole image in memory as it will cause a OutOfMemory exception.
As long as you are fine with an 24 bit PNG file as output I have a working solution for you (under GPL license):
The class PngXxlWriter allows to write PNG files "line by line". That means that you can write an image of 10000x10000 (width * height) pixels in lines of e.g. 256 pixels (10000 * 256).
Usually this reduces the memory usage down to a level which is practically.
All required classes can be found here:
PngXxlWriter is the main class. By calling its method writeTileLine you can add a new line to the output image.
https://sourceforge.net/p/mobac/code/HEAD/tree/trunk/MOBAC/src/main/java/mobac/utilities/imageio/