I'm building a JPEG image encoder. As it stands, in order to encode an image the user enters the name of the file they wish to encode and name of the file to be created as a result.
I'd like the user to be able to set the quality of the encoding in the command line. I tried renaming the second argument (100) in new JpegEncoder(image, 100, new FileOutputStream(args[1]));
encoder.Compress(); to args[2] but that didn't work.
public class JPGencoder {
public static void main ( String[] args ) {
String[] names = ImageIO.getWriterFormatNames();
BufferedImage image = null;
JpegEncoder encoder = null;
try {
image = ImageIO.read( new File( args[0] ) );
System.err.println("Process image " + args[0]);
System.err.println(image.toString());
} catch (Exception e) {
System.err.println("Problems with image " + args[0]);
}
try {
encoder = new JpegEncoder(image, 100, new FileOutputStream(args[1]));
encoder.Compress();
} catch (Exception e) {
System.out.println("well that didn't work");
}
}
}
Based on this definition of JpegEncoder the second argument to the JpegEncode constructor is an int.
The type of args[2] is a String so presumably by "did not work" you mean "did not compile". To convert args[2] to an int:
Integer.parseInt(args[2]);
This will throw a NumberFormatException if args[2] is not a valid int.
It is not difficult to set the JPG compression/quality using ImageIO. Here are some snippets that might get you started.
private ImageWriteParam imageWriterParams;
private ImageWriter imageWriter;
File out = new File("some.jpg");
// ...
Iterator it = ImageIO.getImageWritersBySuffix("jpg");
// presume every iterator has precisely 1 writer
imageWriter = (ImageWriter)it.next();
imageWriterParams = imageWriter.getDefaultWriteParam();
if ( imageWriterParams.canWriteCompressed() ) {
try {
imageWriterParams.setCompressionMode( ImageWriteParam.MODE_EXPLICIT );
} catch(Exception e) {
e.printStackTrace();
}
} else {
logger.log(Level.WARNING, "ImageWriter cannot compress!");
}
imageWriterParams.setCompressionQuality(qualF);
FileImageOutputStream fios = new FileImageOutputStream(out);
imageWriter.setOutput(fios);
imageWriter.write(
null,
new IIOImage(image,null,null),
imageWriterParams );
fios.flush();
fios.close();
Related
(using jfugue 5.0.9) I wanted to convert .mid to .txt (staccato), and later to .mid again, to confirm conversions worked. Both .mid (original and converted) should be equal ideally, but the converted (midi -> staccato -> midi) file has weird delayed notes, and one enlargened note duration. JFugue probably struggles because the midi is a human, hyper-sensible recording. Is there any way to fix this?
Heres the 3 files https://drive.google.com/drive/folders/1DepX0lCqNaIRCoHRfGwBRsO1xRFCbCpl?usp=sharing
And here are the 2 methods used:
public static Pattern convMidToStac(String fileName, boolean makeAFile) {
Pattern p = new Pattern();
// Convert midi file to a JFugue Staccato pattern.
try {
p = MidiFileManager.loadPatternFromMidi(new File("D:/eclipse-workspace/MidiReader/" + fileName + ".mid"));
if (makeAFile) {
makeFile(fileName, p.toString());
}
return p;
} catch (Exception e) {
System.out.println("An error occurred.");
e.printStackTrace();
return null;
}
}
public static void convStacToMid(String fileName) {
Pattern p = new Pattern();
try {
p = MidiFileManager.loadPatternFromMidi(new File("D:/eclipse-workspace/MidiReader/" + fileName + ".mid"));
File filePath = new File("D:/eclipse-workspace/MidiReader/" + fileName + "MIDI.mid");
MidiFileManager.savePatternToMidi(p, filePath);
} catch (Exception e) {
e.printStackTrace();
}
}
I have this code for saving to a text file however, I can't seem to find a way to make it save to not the user.home folder but to another folder on my hard drive. I searched in many places but couldn't really find anything that could help me.
It works with the user.home setting but if I try to change it, it doesn't. The program, when executed, comes up with Source not found.
saveBtn.setOnAction(new EventHandler<ActionEvent>()
{
public void handle(ActionEvent event)
{
Object source = event.getSource();
String s = null;
//Variable to display text read from file
if (_clickMeMode) {
FileOutputStream out = null;
try {
//Code to write to file
String text = titleField.getText();
byte b[] = text.getBytes();
String outputFileName = System.getProperty("user.home"
+ File.separatorChar+"home")
+ File.separatorChar + "Movies2.txt";
out = new FileOutputStream(outputFileName);
out.write(b);
out.close();
//Clear text field
titleField.setText("");
}catch (java.io.IOException e) {
System.out.println("Cannotss text.txt");
} finally {
try {
out.close();
} catch (java.io.IOException e) {
System.out.println("Cannote");
}
}
}
else
{
//Save text to file
_clickMeMode = true;
}
window.setTitle("Main Screen");
window.setScene(mainScreen);
}
});
Your file name is incorrectly assigned:
String outputFileName = System.getProperty("user.home"
+ File.separatorChar+"home")
+ File.separatorChar + "Movies2.txt";
You are passing a string of the form "user.home/home" to System.getProperty().
Since there is no such property, this will return null.
Then you concatenate this with /Movies2.txt, so outputFileName will be something like null/Movies2.txt.
(A simple System.out.println(outputFileName) will confirm this.)
Instead of building the filename by hand like this, you should use a higher-level API to do it. E.g.:
Path outputFile = Paths.get(System.getProperty("user.home"), "home", "Movies2.txt");
OutputStream out = Files.newOutputStream(outputFile);
out.write(b);
If you also need (or might need) to create the directory, you can do
Path outputDir = Paths.get(System.getProperty("user.home"), "home");
Files.createDirectories(outputDir);
Path outputFile = outputDir.resolve("Movies2.txt");
OutputStream out = Files.newOutputStream(outputFile);
out.write(b);
I cant understand why my code are not running all the time.
I am opening a jasper report but for first 4 opening times the report is cached or code are not executing (Code in the new StreamResource are not executing first 4 times). new StreamResource.StreamSource() are running only at 5 time WHY ? The first 4 times i got the old,cached,temp or i event dont know what a pdf file with old params.
maybe someone know the issue ?
public static void open(final String fileName, final HashMap<String, Object> data ) {
mylog.pl("### Param's print # open Report: Filename:" + fileName);
try {
Iterator<?> i = data.keySet().iterator();
while (i.hasNext()) {
String id = i.next().toString();
String value = (data.get(id) != null) ? data.get(id).toString() : "null";
mylog.pl(" id: " + id + " value: " + value);
}
} catch (Exception e) {
e.printStackTrace();
mylog.pl(e.getMessage());
}
StreamResource.StreamSource source = null;
source = new StreamResource.StreamSource() {
public InputStream getStream() {
byte[] b = null;
InputStream reportStream = null;
try {
reportStream = new BufferedInputStream(new FileInputStream(PATH + fileName + JASPER));
b = JasperRunManager.runReportToPdf(reportStream, data, new JREmptyDataSource());
} catch (JRException ex) {
ex.printStackTrace();
mylog.pl("Err # JR" + ex.getMessage());
} catch (FileNotFoundException e) {
e.printStackTrace();
Utils.showMessage(SU.NOTFOUND);
return null;
}
return new ByteArrayInputStream(b);
}
};
StreamResource resource = null;
resource = new StreamResource(source, fileName + PDF);
resource.setMIMEType("application/pdf");
Page p = Page.getCurrent();
p.open(resource, "Report", false);
}
Here is the answer
I all the time used resource.setCacheTime(0); but really needed resource.setCacheTime(1000); because
In theory <= 0 disables caching. In practice Chrome, Safari (and,
apparently, IE) all ignore <=0.
I have been attempting to use Zxing 2.3.0 to read images of UPC barcodes with a +5 supplement in java however i cannot read the supplement portion of the barcode. The code successfully reads the first portion only. After searching multiple websites i cannot find any further indications of how to read the supplement other than my current method. Any help would greatly be appreciated.
public static void main(String[] args) {
decodeUPC5();
}
public static void decodeUPC5(){
InputStream barCodeInputStream = null;
try {
barCodeInputStream = new FileInputStream("C:/Users/apoclyps/git/zxing-barcoder/Zxing-Test/img/upc5.png");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedImage barCodeBufferedImage = null;
try {
barCodeBufferedImage = ImageIO.read(barCodeInputStream);
} catch (IOException e) {
e.printStackTrace();
}
LuminanceSource source = new BufferedImageLuminanceSource(barCodeBufferedImage);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
// Attempting to read UPC + 5 Supplement
GenericMultipleBarcodeReader multiReader = new GenericMultipleBarcodeReader(new MultiFormatReader());
try {
multiReader.decodeMultiple(bitmap);
} catch (NotFoundException e1) {
e1.printStackTrace();
}
Result[] result = null;
try {
result = multiReader.decodeMultiple(bitmap);
} catch (NotFoundException e) {
e.printStackTrace();
}
System.out.println("Results length "+result.length);
for(Result r : result ){
System.out.println("Barcode text is " + r.toString());
}
}
Barcode image!
Output
Results length 1
Barcode text is 9780735200449
Keep in mind that the content of the barcode is 9780735200449 and not 9780735200449 51299. It will always (correctly) return the 9780735200449 as the contents of the barcode.
The +5 extension is returned as ResultMetadata, under key ResultMetadatatype.UPC_EAN_EXTENSION.
Note that it will still return the UPC barcode even if it doesn't see a +5 extension, obviously. So it's possible you would see it return without a +5 extension on this image. However it works for me with the app and so would imagine it easily detects the +5. (If you scan with the app, look at the left for "Metadata $12.99")
I had a problem with reading /proc/%d/stat files using my Java method copyFiles() (source code below).
I have found workaround using similar readProc() method.
Now I am wondering what was the problem. Output files were created, but each file had 0 bytes (in /proc/ all files are 0 bytes because it is not standard filesystem). FileUtils is from the Apache Commons IO library.
I've tried to do the same using java.nio - again, IOException is being thrown that attributes are wrong for each file.
I removed some part of the code regarding parsing exceptions etc.
Why does this work with FileInputStream, but not with FileUtils.copyFile()?
public void copyFiles() {
final File dir = new File("/proc");
final String[] filedirArray = dir.list();
long counter = 0;
for(String filedir : filedirArray) {
final File checkFile = new File(dir, filedir);
if (checkFile.isDirectory()) {
try {
Integer.parseInt(filedir);
File srcFile = new File(checkFile, "stat");
File dstFile = new File("/home/waldekm/files/stat" + "." + Long.toString(counter++));
try {
FileUtils.copyFile(srcFile, dstFile);
} catch (IOException e1) {}
} catch (NumberFormatException e) {
// not a number, do nothing
}
}
}
}
public static void readProc(final String src, final String dst) {
FileInputStream in = null;
FileOutputStream out = null;
File srcFile = new File(src);
File dstFile = new File(dst);
try {
in = new FileInputStream(srcFile);
out = new FileOutputStream(dstFile);
int c;
while((c = in.read()) != -1) {
out.write(c);
}
} catch (IOException e1) {
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e1) {}
try {
if (out != null) {
out.close();
}
} catch (IOException e1) {}
}
The reason is most likely that the operating system is reporting the file size as zero.
On my machine, man 2 stat says this:
"For most files under the /proc directory, stat() does not return the file size in the st_size field; instead the field is returned with the value 0."
(The stat system call will be what the JVM uses to find out what a file's size is.)
Here is a code snipped that would read specific fields from a proc file, using methods that are available (but not documented directly) in the Process class of Android. Modify the FORMAT buffer and the output buffer size to read more/different values from the proc file,
int PROC_SPACE_TERM = (int)' ';
int PROC_OUT_LONG = 0x2000
public static final int[] PROCESS_STATS_FORMAT = new int[] {
PROC_SPACE_TERM,
PROC_SPACE_TERM,
PROC_SPACE_TERM,
PROC_SPACE_TERM,
PROC_SPACE_TERM,
PROC_SPACE_TERM,
PROC_SPACE_TERM,
PROC_SPACE_TERM,
PROC_SPACE_TERM,
PROC_SPACE_TERM,
PROC_SPACE_TERM,
PROC_SPACE_TERM,
PROC_SPACE_TERM,
PROC_SPACE_TERM|PROC_OUT_LONG, // 13: utime
PROC_SPACE_TERM|PROC_OUT_LONG // 14: stime
};
long buf[] = new long[2];
try {
int pid = 1000; // Assume 1000 is a valid pid for a process.
Method mReadProcFile =
Process.class.getMethod("readProcFile", String.class,
int[].class, String[].class,
long[].class, float[].class);
mReadProcFile.invoke(null, "/proc/" + pid + "/stat",
PROCESS_STATS_FORMAT, null, buf, null);
return buf;
} catch(NoSuchMethodException e) {
Log.e(TAG, "Error! Could not get access to JNI method - readProcFile");
} catch (InvocationTargetException e) {
Log.e(TAG, "Error! Could not invoke JNI method - readProcFile");
} catch (IllegalAccessException e) {
Log.e(TAG, "Error! Illegal access while invoking JNI method - readProcFile");
}
return null;
I see you are creating a FileInputStream to read a /proc file. Instead I suggest you create a FileReader object. FileInputStream gets tripped up by the lack of file length for /proc files but FileReader does not.