Recently I have got involved into Storlet project which is a middleware of OpenStack Swift Project. I do not intend to talk about Storlet but, in short Storlet running a java code on objects(files) that stored into swift object storage. Files read by the storlet and send to the java application in form of InputSream which means we don't direct access to files.
this is a sample code of a storlet which gets the image as an inputstream and make a thumbnail of it.
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.io.InputStream;
import java.io.OutputStream;
import org.openstack.storlet.common.IStorlet;
import org.openstack.storlet.common.StorletException;
import org.openstack.storlet.common.StorletInputStream;
import org.openstack.storlet.common.StorletLogger;
import org.openstack.storlet.common.StorletObjectOutputStream;
import org.openstack.storlet.common.StorletContainerHandle;
import org.openstack.storlet.common.StorletOutputStream;
import org.openstack.storlet.common.StorletUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
public class ThumbnailStorlet implements IStorlet {
#Override
public void invoke(ArrayList<StorletInputStream> inputStreams,
ArrayList<StorletOutputStream> outputStreams,
Map<String, String> parameters, StorletLogger log)
throws StorletException {
log.emitLog("ThumbnailStorlet Invoked");
/*
* Get input stuff
*/
HashMap<String, String> object_md;
StorletInputStream storletInputStream = inputStreams.get(0);
InputStream thumbnailInputStream = storletInputStream.getStream();
object_md = storletInputStream.getMetadata();
/*
* Get output stuff
*/
StorletObjectOutputStream storletObjectOutputStream = (StorletObjectOutputStream)outputStreams.get(0);
OutputStream thumbnailOutputStream = storletObjectOutputStream.getStream();
/*
* Set the output metadata
*/
log.emitLog("Setting metadata");
storletObjectOutputStream.setMetadata(object_md);
/*
* Read Input to BufferedImage
*/
log.emitLog("Reading Input");
BufferedImage img = null;
try {
img = ImageIO.read(thumbnailInputStream);
} catch (Exception e) {
log.emitLog("Failed to read input stream to buffered image");
throw new StorletException("Failed to read input stream to buffered image " + e.getMessage());
} finally {
try {
thumbnailInputStream.close();
} catch (IOException e) {
log.emitLog("Failed to close input stream");
}
}
try {
thumbnailInputStream.close();
} catch (IOException e) {
log.emitLog("Failed to close input stream");
}
/*
* Convert
*/
log.emitLog("Converting");
int newH = img.getHeight()/8;
int newW = img.getWidth()/8;
int type = img.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage thumbnailImage = new BufferedImage(newW, newH, type);
Graphics2D g = thumbnailImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, newW, newH, null);
g.dispose();
/*
* Write
*/
log.emitLog("Writing Output");
try {
ImageIO.write(thumbnailImage, "PNG" , thumbnailOutputStream);
} catch (Exception e) {
log.emitLog("Failed to write image to out stream");
throw new StorletException("Failed to write image to out stream " + e.getMessage());
} finally {
try {
thumbnailOutputStream.close();
} catch (IOException e) {
}
}
try {
thumbnailOutputStream.close();
} catch (IOException e) {
}
log.emitLog("Done");
}
}
Now ..
I want to using some external application which running on images such as GDAL inside my java code ,assume code like the code above(not exactly doing the same as above). GDLA has some cli commands. For example this command
gdal_translate -of JPEG -co QUALITY=50 input.tif output.jpg
The input.tif has already stored into my object storage and storlet can read it and give it to me as inputstream, also I have some practice how to run external process inside java with java ProcessBuilder but, imagine I receive input.tif as InputStream not a file.
Next, I don't want to write back InputStream to local storage where my application running there because of lack of storage ( maybe the object are very large, more the 2GBs) and also degrading performance.
Is there any way in java to pass InputStream to external process as a file argument without storing it on disk.
I am running my code on Ubuntu Docker
I donĀ“t think you can do that, a File needs to be stored in a File system (either local or remote) to be read. You could try to base a ByteArrayInputStream to the reading process but the GDAL process should support that type of input:
https://gdal.org/programs/gdal_translate.html#cmdoption-gdal_translate-arg-src_dataset
As per the GDAL documentation, it does not seem possible:
<src_dataset>
The source dataset name. It can be either file name, URL of data source or subdataset name for multi-dataset files.
Related
I'm attempting to run an Access function through Java using Jacob using Application.Run (https://msdn.microsoft.com/en-us/library/office/ff193559.aspx). I am able to open and close an Access database, but not run a function. I suspect the run call actually does go through but that I have opened the file read-only (maybe? not sure I did) which then causes the Access error: Run-time error 3073: Operation must use an updatable query. The query simply appends two strings onto a test table I created, and that query works by hand, but so far not through Java.
If the error is that I've opened it read-only, how can I open it not read-only? If it's something else, how do I call a function (or a macro, either will work) using Jacob? Or you may know some other Java technique besides using Jacob, I'd take that too.
Minimum example:
Java program
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.LibraryLoader;
import com.jacob.com.Variant;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author evans
*/
public class Test {
public static void main(String[] args) {
// Load library/.dll
try {
String libFile = System.getProperty("os.arch").equals("amd64") ? "jacob-1.18-x64.dll" : "jacob-1.18-x86.dll";
FileInputStream inputStream = new FileInputStream(new File(libFile));
File temporaryDll = File.createTempFile("jacob", ".dll");
try (FileOutputStream outputStream = new FileOutputStream(temporaryDll)) {
byte[] array = new byte[8192];
for (int i = inputStream.read(array); i != -1; i = inputStream.read(array)) {
outputStream.write(array, 0, i);
}
}
System.setProperty(LibraryLoader.JACOB_DLL_PATH, temporaryDll.getAbsolutePath());
LibraryLoader.loadJacobLibrary();
temporaryDll.deleteOnExit();
} catch (IOException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
// Open thread
ComThread.InitSTA(true);
// New application
ActiveXComponent ComBridge = new ActiveXComponent("Access.Application");
// Open database
Dispatch.put(ComBridge, "Visible", new Variant(true));
ComBridge.invoke("OpenCurrentDatabase", new Variant("C:/Users/evans/Documents/Book Business/Building Reports/Book Business.accdb"));
// Run function
ComBridge.invoke("Run", new Variant("Test"));
// Shutdown
ComBridge.invoke("Quit");
ComThread.quitMainSTA();
ComThread.Release();
}
}
Access query:
INSERT INTO tblTest ( Test, Test2 )
SELECT "a" AS Expr1, "B" AS Expr2;
I have images of codes that I want to decode. How can I use zxing so that I specify the image location and get the decoded text back, and in case the decoding fails (it will for some images, that's the project), it gives me an error.
How can I setup zxing on my Windows machine? I downloaded the jar file, but I don't know where to start. I understand I'll have to create a code to read the image and supply it to the library reader method, but a guide how to do that would be very helpful.
I was able to do it. Downloaded the source and added the following code. Bit rustic, but gets the work done.
import com.google.zxing.NotFoundException;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.Reader;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.Result;
import com.google.zxing.LuminanceSource;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.util.*;
import com.google.zxing.qrcode.QRCodeReader;
class qr
{
public static void main(String args[])
{
Reader xReader = new QRCodeReader();
BufferedImage dest = null;
try
{
dest = ImageIO.read(new File(args[0]));
}
catch(IOException e)
{
System.out.println("Cannot load input image");
}
LuminanceSource source = new BufferedImageLuminanceSource(dest);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Vector<BarcodeFormat> barcodeFormats = new Vector<BarcodeFormat>();
barcodeFormats.add(BarcodeFormat.QR_CODE);
HashMap<DecodeHintType, Object> decodeHints = new HashMap<DecodeHintType, Object>(3);
decodeHints.put(DecodeHintType.POSSIBLE_FORMATS, barcodeFormats);
decodeHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
Result result = null;
try
{
result = xReader.decode(bitmap, decodeHints);
System.out.println("Code Decoded");
String text = result.getText();
System.out.println(text);
}
catch(NotFoundException e)
{
System.out.println("Decoding Failed");
}
catch(ChecksumException e)
{
System.out.println("Checksum error");
}
catch(FormatException e)
{
System.out.println("Wrong format");
}
}
}
The project includes a class called CommandLineRunner which you can simply call from the command line. You can also look at its source to see how it works and reuse it.
There is nothing to install or set up. It's a library. Typically you don't download the jar but declare it as a dependency in your Maven-based project.
If you just want to send an image to decode, use http://zxing.org/w/decode.jspx
In my auto updater application i am downloading a zipped file that contains the new MyApp.app application file. So i am downloading MyApp.zip.. Then i use this following class to try and unzip it:
package update;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
public class UnZip {
public static final void copyInputStream(InputStream in, OutputStream out)
throws IOException
{
byte[] buffer = new byte[1024];
int len;
while((len = in.read(buffer)) >= 0)
out.write(buffer, 0, len);
in.close();
out.close();
}
public static final void unZipIt(String F1, String F2) {
Enumeration entries;
ZipFile zipFile;
try {
zipFile = new ZipFile(F1);
entries = zipFile.entries();
while(entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry)entries.nextElement();
if(entry.isDirectory()) {
// Assume directories are stored parents first then children.
System.err.println("Extracting directory: " + entry.getName());
// This is not robust, just for demonstration purposes.
(new File(entry.getName())).mkdirs();
continue;
}
System.err.println("Extracting file: " + entry.getName());
copyInputStream(zipFile.getInputStream(entry),
new BufferedOutputStream(new FileOutputStream(entry.getName())));
}
zipFile.close();
} catch (IOException ioe) {
System.err.println("Unhandled exception:");
ioe.printStackTrace();
return;
}
}
}
However after the unzip the application wont launch.. any ideas?
Your executable file is most likely not flagged as executable. The trick is that .app "files" are in fact directories, so making them executable serves no practical purpose, you need to find the actual binary.
To do that, you need to open ./myApp.app/Contents/Info.plit and look for the CFBundleExecutable key: the associated string is the path of the executable file, relative to ./myApp.app/Contents/MacOS, I believe.
Once you've found that file, chmod +x it, and check whether your application still fails to start.
If it doesn't, problem solved.
If it does, try and open your application from the terminal through the open ./myApp.app command. If anything odd is printed, update your question with it and let us know what that was.
If all else fails, look into the Console application for interesting log entries - you can search for your application's name, see if anything comes up.
I am working on a concept of a filesystem for a program. I am writing in Java (using JDK 7 u17).
To get started I built off of some tutorial that were showing my how to create a zip based filesystem using the FileSystemProvider class.
When I execute the code I have it do similar task to the examples which is copy a text file from the my desktop and place it in the zip file. The problem is once it copies the file it does not write it into the zip file, it seems to leave the file in memory which is destroyed when the program is terminated.
The problem is I cannot understand why, as far as I can tell everything looks to be in order but something is clearly not!
Oh yeah the same thing goes for directories too. If I tell the filesystem to make a new directory it just creates it in memory and there is nothing in the zip file.
Anyhow here is my working code;
import java.io.IOException;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class Start {
public static void main(String[] args) {
Map <String, String> env = new HashMap<>();
env.put("create", "true");
env.put("encoding", "UTF-8");
FileSystem fs = null;
try {
fs = FileSystems.newFileSystem(URI.create("jar:file:/Users/Ian/Desktop/test.zip"), env);
} catch (IOException e) {
e.printStackTrace();
}
Path externalTxtFile = Paths.get("/Users/Ian/Desktop/example.txt");
Path pathInZipFile = fs.getPath("/example.txt");
try {
Files.createDirectory(fs.getPath("/SomeDirectory"));
} catch (IOException e) {
e.printStackTrace();
}
if (Files.exists(fs.getPath("/SomeDirectory"))) {
System.out.println("Yes the directory exists in memory.");
} else {
System.out.println("What directory?");
}
// Why is the file only being copied into memory and not written out the jar/zip archive?
try {
Files.copy(externalTxtFile, pathInZipFile);
} catch (IOException e) {
e.printStackTrace();
}
// The file clearly exists just before the program ends, what is going on?
if (Files.exists(fs.getPath("/example.txt"))) {
System.out.println("Yes the file has been copied into memory.");
} else {
System.out.println("What file?");
}
}
}
I just want to add something.
Perhaps the example that you found was incomplete (I can not check since you do not references it) but in all examples I found the FileSystem instance is closed properly.
The FileSystem abstract class implements Closeable, so the close() method is called (automatically) leaving the try in the following code:
try (final FileSystem fs = FileSystems.newFileSystem(theUri, env)) {
/* ... do everything you want here ; do not need to call fs.close() ... */
}
http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
I used a screenshot plugin for ios when I developed an iphone/ipad app. I am now creating an android version of the app and am trying to implement the android version of the plugin.
My java part fo the plugin looks like this:
package org.apache.cordova;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import android.graphics.Bitmap;
import android.os.Environment;
import android.view.View;
public class Screenshot extends Plugin {
private PluginResult result = null;
#Override
public PluginResult execute(String action, JSONArray args, String callbackId) {
// starting on ICS, some WebView methods
// can only be called on UI threads
super.cordova.getActivity().runOnUiThread(new Runnable() {
public void run() {
View view = webView.getRootView();
view.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
try {
File folder = new File(Environment.getExternalStorageDirectory(), "Pictures");
if (!folder.exists()) {
folder.mkdirs();
}
File f = new File(folder, "screenshot_" + System.currentTimeMillis() + ".png");
FileOutputStream fos = new FileOutputStream(f);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
result = new PluginResult(PluginResult.Status.OK);
} catch (IOException e) {
result = new PluginResult(PluginResult.Status.IO_EXCEPTION, e.getMessage());
}
}
});
// waiting ui thread to finish
while (this.result == null) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// ignoring exception, since we have to wait
// ui thread to finish
}
}
return this.result;
}
}
My Screenshot.js looks like this:
(function() {
/* Get local ref to global PhoneGap/Cordova/cordova object for exec function.
- This increases the compatibility of the plugin. */
var cordovaRef = window.PhoneGap || window.Cordova || window.cordova; // old to new fallbacks
/**
* This class exposes the ability to take a Screenshot to JavaScript
*/
function Screenshot() { }
/**
* Save the screenshot to the user's Photo Library
*/
Screenshot.prototype.saveScreenshot = function() {
cordovaRef.exec(null, null, "Screenshot", "saveScreenshot", []);
};
if (!window.plugins) {
window.plugins = {};
}
if (!window.plugins.screenshot) {
window.plugins.screenshot = new Screenshot();
}
})(); /* End of Temporary Scope. */
Now I try to call my screenshot.js function by using this code:
function takeScreenShot() {
cordovaRef.exec("Screenshot.saveScreenshot");
}
However all I get is JSON errors, I know somewhere im asking to to convert it to JSON from a java string but i just can't figure out how to change it. Ok well I think that is what is wrong...
My errors look like this:
ERROR: org.json.JSONException: Value undefined of type java.lang.String cannot be converted to JSONArray.
Error: Status=8 Message=JSON error
file:///android_asset/www/cordova-2.0.0.js: Line 938 : Error: Status=8 Message=JSON error
Error: Status=8 Message=JSON error at file:///android_asset_/www/cordova-2.0.0.js:938
Can anyone guide me where Im going wrong please?
Question resolved by:
Phonegap Screenshot plugin in Cordova 2.0.0
Answer provided by Simon MacDonald.