Java saving large images in threads - IP camera broken images - java

After clicking a button in my app, it creates new normal Thread and start downloading large image and saving it to file. Everything is going well, but when i click button more than once it's going without errors and when i try to view these images they're bugged like they re overwriting themself.
I don't have any idea how to debug it.
localPath = today + "/" + productCode + "/" + this.placeId; //Unique
/* ... */
private void productSave(String productCode, int whichCamera, boolean isError) {
for (int i = position; i < lastCamera; i++) {
Date dateSave = new Date();
path = localPath + "/" + dateFormat.format(dateSave) + "_" + (i + 1) + ".jpg";
try {
BufferedImage imageOld = ImageIO.read(new URL(this.camerasUrlsToSave[i]));
ImageIO.write(imageOld, "jpg", new File(rootPath + "/" + path));
ComDb.getInstance().saveProduct(productCode, this.placeId, path, dateSave);
} catch (IOException ex) {
result = false;
}
}
}
EDIT: path is 100% unique (different folders with product code). And it shoudn't be problem with image from camera - I can open 10 cards i dont see image bugs
EDIT2: Can it be something like downloading Img bufor? Cause all images are downloaded from the same IP. Or maybe its problem with bufferedimg memory leaks. Need idea how to repair it.
EDIT3: I found that if i open 5 cards in web browser with my camera address like : blah.blah.some.ip/GetImage.cgi?CH=0 They're loading one after the other, not all at once. But, i dont see bugged images when downloading ends.
EDIT4: I tried to reproduce this bug in web browser, if i try to open link in ff and in IE. IE prints "getImage busy". When I try ff and chrome i got broken images. So i have to do sth like queue or disable button ...
EDIT5: My temporary solution: synchronized function productSave. Images from second click will be saved few seconds later.
http://oi57.tinypic.com/ofrrn.jpg!
One from saved Images

First action of the click event for the button should be to disable the button and maybe change the text to "In process". Last action should be to re-enable the button and restore the text.

This answer is a guess as you have not given full code, issue could be with variable i - where is it from?
Or could be same file name is being reused, mnake sure that is nto the case by getting unique file name from a seperate function something like this:
if dateFormat is only to minute or second, same file name might be used for 2 images use this API of java.io.File to get a unique name
http://docs.oracle.com/javase/7/docs/api/java/io/File.html#createTempFile%28java.lang.String,%20java.lang.String,%20java.io.File%29
public static File createTempFile(String prefix,
String suffix,
File directory)
//you can pass extn as jpg
public File getFileName(File localPath ,Date dateSave, int i, String extn){
File fileUniqe = File.createTempFile(dateSave + "_" + (i+1), extn, localPath );
return fileUniqe,
}

Related

Trying to update CSV file with Java, but file size keeps increasing although the code empties its content

I am coding with Java and I am trying to write in some forex data into a CSV file. I want the CSV file to be constantly the latest 277 datas without stacking on top of old data. So I used the "new FileWriter(file, false).close();" to empty the former data every time before the program writes in data. The code works as the newest Data starts always from index 1 in CSV opened with excel and the rest are blank. But the csv file size keeps increasing. Could anyone give me any ideas on how to modify the code so that the file size would not increase indefinitely?
//this is the inside of a loop that starts every time a candle stick gets formed
try {
new FileWriter(file, false).close();
} catch (Exception e) {
console.getErr().println(e.getMessage());
e.printStackTrace(console.getErr());
context.stop();
}
int shift = 1;
while (shift < 278){
IBar bar = history.getBar(Instrument.USDJPY, Period.FIVE_MINS, OfferSide.BID, shift);
try {
out.write(dateFormat.format(bar.getTime()) + "," + priceFormat.format(bar.getOpen()) + "," + priceFormat.format(bar.getHigh()) + ","
+ priceFormat.format(bar.getLow()) + "," + priceFormat.format(bar.getClose()) + "," + priceFormat.format(askBar.getVolume()) + "\r\n");
} catch (Exception e) {
console.getErr().println(e.getMessage());
e.printStackTrace(console.getErr());
context.stop();
}
shift+=1;
}//while
try {
out.flush();
} catch (Exception e) {
console.getErr().println(e.getMessage());
e.printStackTrace(console.getErr());
context.stop();
}
Edit: I opened the CSV with notepad and saw an egregious amount of space and had to scroll far down to see the data. When I open properties of the CSV files, the size says 253 KB but the "size on disk" is 3.87 mb, which I don't understand. Anyway to solve this?
Edit2: Stopping the program on the Fx platform app from running presumably closed the Bufferwriter named "out" and the "size on disk" returns to normal. But still no idea on the space problem. Also somehow I can't manually edit it with notepad, it says I have no access to change the file when I attempt to save. I am new to programming so I don't know what did that either. Thank you.
Edit3: Solved it. The out.flush was the culprit, replaced it with out.close, and create a new bufferwriter named "out" every time this class gets started.

How to retrieve & share bitmap from device folder

I am building a meme generator app. So far, the app does everything I need it to do but I want to add 1 more functionality. The app saves the meme as a bitmap on my device. I want to add a functionality where, if the user wishes to share the meme on Facebook, Twitter, IG, etc, the app retrieves that same bitmap (which was just created.).
I'm not worried about the sharing function at the moment. I want to find out how I can retrieve the file to be able to share it.
This is the method where the creation and saving of the meme takes place. I will omit unnecessary code:
public void createBitmapAndSave(ImageView img) {
...
counter++;
File file;
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath();
file = new File(path + "/SimpliMeme/" + timeStamp + "-" + counter + ".jpg");
file.getParentFile().mkdir();
try {
OutputStream stream = new FileOutputStream(file);
mutableBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
stream.flush();
stream.close();
Toast.makeText(getContext(), "Top Text: " + String.valueOf(topTextMeasurement) + " and bottom text: " + String.valueOf(bottomTextMeasurement),
Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
Objects.requireNonNull(getContext()).sendBroadcast(mediaScanIntent);
}
and I've created an empty method that needs to be called when the user hits the "Share" button:
public void shareMeme(){}
Like you've mentioned earlier, you gotta divide this big method into 2 small ones.
As far as your initial question goes: There is no point in going back to your device just to find and get that same photo. Divide the method into 2 methods (createBitmap() & saveBitmap(), for example) and if the user just wants to share it without saving it to the device, the app will just call the createBitmap() method to only create the bitmap and then you'll use that in your upcoming sharing functionality.

Can't add image to a button using getResource() (get NullPointerException- building project with ant)

I know that this a very common error, and I've read dozens of posts about such errors on SO already, but for some reason, absolutely nothing seems to be working out.
My ultimate object is to read an image from a particular location (in specific, the data folder) that is present at the same level as src in the project folder, and create a button with that image. However, I seem unable to read the image, and keep getting null.
Moreover, I have tried all possible combination I could think of:
gitinit.png
//gitinit.png
\gitinit.png
/gitinit.png
\gitinit.png
data/gitinit.png
data//gitinit.png
data\gitinit.png
data\gitinit.png
all out of sheer, meaningless frustration...
I'm using Eclipse. However, the project is being built with ant.
Here is the structure of my project:
As is visible, I've added gitinit.png everywhere possible, but to no avail.
As I read somewhere, I even tried adding data folder into the build path, but yet again, hopeless.
I realize that in this case, absolute path of the form "/data/gitinit.png" would be ideal, but here's another issue. What I'm working on is a tool for Processing. The tool is called from within Processing when it is running. When I run
System.out.println(this.getClass().getResource("/").getPath());
I get the following output:
/C:/Program%20Files/processing-2.1.1-windows64/processing-2.1.1/lib/
(with the / before C:). This folder has the following contents:
but when I run
System.out.println(this.getClass().getResource("").getPath());
I get the following output:
file:/C:/Users/MYPC/Documents/Processing/tools/GitManager/tool/GitManager.jar!/git_manager/tool/
The contents of this jar file are:
Here is the code I used. I've used 3 different ways of doing it (one of them came in the Processing Tool Template repo's readme), though they all essentially do the same thing. Again, the ultimate aim is to load an icon onto the button.
// some other function that executes during runtime
ImageIcon init = createImageIcon("gitinit.png", "git init Icon");
System.out.println("-------------------------------------");
loadImage("gitinit.png");
b.setIcon(new ImageIcon(("src\\gitinit.png")));
System.out.println(b.getIcon());
public Image loadImage(String theFilename) {
if (theFilename.startsWith(File.separator)) {
return new ImageIcon(theFilename).getImage();
} else {
URL img;
try{
img = this.getClass().getResource(getPath(theFilename));
return new ImageIcon(img).getImage();
}
catch (NullPointerException n)
{
//System.out.println("Null pointer Exception");
n.printStackTrace();
return null;
}
}
}
protected ImageIcon createImageIcon(String path, String description) {
java.net.URL imgURL;
try{
//imgURL = GitOptionToolbar.class.getResource(path);
imgURL = GitOptionToolbar.class.getClass().getResource(path);
}
catch(NullPointerException n)
{
imgURL = null;
System.out.println("null");
}
if (imgURL != null) {
System.out.println("Found " + path);
return new ImageIcon(imgURL, description);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
public String getPath(String theFilename) {
if (theFilename.startsWith("/")) {
return theFilename;
}
return File.separator + "data" + File.separator + theFilename;
}
So, well, what I think is to be done is to somehow move up the present path by 3 levels, then use the relative "data/gitinit.png", or "data/tools/xyz.png", but how do I do this?
Also, is this hypothesis correct??
I know this question is really long, and I'm sorry, I just wanted to put forth all of my experiments till now. Further, I know a lot of things are random, especially trying out different combinations of foldername, /, \ and filename, and also putting gitinit.png in every possible folder, and I apologize for that as well. Its just that I wanted to try out everything I could before posting here :)
Thanks!
You need to use
getResource("/data/toolbar/logos/gitnit.png")
The complete path from data all the way to the image. I'n not used to using Eclispe and not used to having the "data" dir on the same level at the src. In Netbeans I have it in the src, but it looks like the Eclipse takes care of that for you, looking at your image.

making and storing a barcode image from a barcode URL (Barcode4J)

I'm not very familiar with barcodes or barcode4j. I have a URL of the barcode and need to connect to that URL, stream it in order to make an image from it, then store that image somewhere on the file system.
does anyone have experience doing this with Barcode4J?
below i make the url...
private BarcodeRequestBean barCodeProcess(ResponseWithBarCode barCode)throws Exception
{
//hard coding bar code encoding and font size time being
String barCodeNum = ((ResponseWithBarCode)barCode).getBarCodeNumber();
logger.info("Please check below barcode generating parameters if generation failed:");
logger.info("BarCode Number = " + barCodeNum);
if (StringUtils.isEmpty(barCodeNum)||(barCodeNum==null))
{
throw new Exception("ResponseWithBarCode returned invalid barCodeNumber value!");
}
BarcodeRequestBean barbean = new BarcodeRequestBean();
//set bar code number
barbean.setMsg(barCodeNum); //reference number
//set default value
barbean.setType(config.getString("barcode.encoding")); //ex:code128
barbean.setHumanReadableSize(config.getString("barcode.font.size")); //ex:3pt
barbean.setWideFactor(config.getString("barcode.wide.factor")); //wide factor: 2
barbean.setFormat(config.getString("barcode.file.format")); //file format: png
barbean.setHeight(config.getString("barcode.height")); //heigh:1cm
barbean.setModuleWidth(config.getString("barcode.module.width")); //Module width: 0.15mm
return barbean;
}
I have a string of the url as such:
String genbc = barCodeProcess(barCode).toURL();
Perhaps you should learn to think more clear about your work.
Solving this issue, from what I understand, has nothing to do with bar codes. You have an image, that is available through an URL, and you must download it. That problem has been viewed many times on stack overflow and you would have found it if you did the search: "java downloading an image". It was the first result that came up for me in google.

Textscreen in Codename One, how to read text file?

I want to add a help screen to my Codename One App.
As the text is longer as other strings, I would like put it in a separate file and add it to the app-package.
How do I do this? Where do I put the text file, and how can I easily read it in one go into a string?
(I already know how to put the string into a text area inside a form)
In the Codename One Designer go to the data section and add a file.
You can just add the text there and fetch it using myResFile.getData("name");.
You can also store the file within the src directory and get it using Display.getInstance().getResourceAsStream("/filename.txt");
I prefer to have the text file in the filesystem instead of the resource editor, because I can just edit the text with the IDE. The method getResourceAsStream is the first part of the solution. The second part is to load the text in one go. There was no support for this in J2ME, you needed to read, handle buffers etc. yourself. Fortunately there is a utility method in codename one. So my working method now looks like this:
final String HelpTextFile = "/helptext.txt";
...
InputStream in = Display.getInstance().getResourceAsStream(
Form.class, HelpTextFile);
if (in != null){
try {
text = com.codename1.io.Util.readToString(in);
in.close();
} catch (IOException ex) {
System.out.println(ex);
text = "Read Error";
}
}
The following code worked for me.
//Gets a file system storage instance
FileSystemStorage inst = FileSystemStorage.getInstance();
//Gets CN1 home`
final String homePath = inst.getAppHomePath();
final char sep = inst.getFileSystemSeparator();
// Getting input stream of the file
InputStream is = inst.openInputStream(homePath + sep + "MyText.txt");
// CN1 Util class, readInputStream() returns byte array
byte[] b = Util.readInputStream(is);
String myString = new String(b);

Categories