I'm generating a base64 image source at server side and then retrieving it to GWT client through async calls. Unfortunatelly, images are not showing after the callback ends (everything is working fine), but it is shown after a second callback. I have tryied to catch onLoad event immediatelly after creating the Image object, but it was no good.
Thanks!
Edit 1
After some investigation, it is a matter of dimensions, I mean, the base64 is there and the image tag is created correctly, but width and height are setted both to 0.
Edit 2
This is how I'm placing the image in the website:
import net.customware.gwt.dispatch.server.Dispatch
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Image;
dispatch.execute(action, new AsyncCallback<GenerateImageResult> () {
#Override
public void onFailure(Throwable caught) {};
#Override
public void onSuccess(GetCarpetasResult result) {
String base64 = result.getBase64();
Image image = new Image(base64);
RootPanel.get().add(image);
}
});
I've been able to successfully display (in google-chome) base64 image data using this:
String base64= "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAbGxt/2xsbf9sbG3/bGxt/2xsbf9sbG3/bGxt/2xsbf9sbG3/bGxt/2xsbf9sbG3/bGxt/2xsbf8AAAAAAAAAAGxsbf9sbG3/bGxt/2xsbf9sbG3/bGxt/2xsbf9sbG3/bGxt/2xsbf9sbG3/bGxt/2xsbf9sbG3/AAAAAAAAAABsbG3/bGxt/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsbG3/bGxt/wAAAAAAAAAAbGxt/2xsbf8AAAAAbGxt/2xsbf9sbG3/bGxt/2xsbf9sbG3/bGxt/2xsbf8AAAAAbGxt/2xsbf8AAAAAAAAAAGxsbf9sbG3/AAAAAGxsbf9sbG3/bGxt/2xsbf9sbG3/bGxt/2xsbf9sbG3/AAAAAGxsbf9sbG3/AAAAAAAAAABsbG3/bGxt/wAAAAAAAAAAAAAAAAAAAAAAAAAAVHibFE94oDxKeKRkRHiqkUx4ohlsbG3/bGxt/wAAAAAAAAAAAAAAAAAAAABLeKMPPHixUj54sIQ+eLC5Pniw3j54sP8/eK//QXet/0J2q/9Ed6k+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPXiwKkF4rf9BeK3/QXit/0J3q+xFdqnAQ3erhTt7s1Qqg8VSFY3cWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD94rwlCeKxzRHaqUUR2qis7e7MIAAAAABiM2QwJk+hyA5fv4gKX7v8AmfIbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZPoGQOX7oIDlu7tBZXs/wSX6+wJkeqCHXjmTiBy6QIAAAAAAAAAAAAAAAAAAAAAAAAAAA+R4QICl+4kA5fuhgWW7PMGlev/BpXr6wSY64MNjOkQJ23lTC9j5PwuZOSBAAAAAAAAAAAAAAAAAAAAAAAAAAAElu0JBpXr1QaV6/8GlevpBpbrfASY6xcAAAAAK2fkNi5k5PgsZuT4LGbkRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaV62wGlet+BZbrFQAAAAAAAAAALWTkIi1l5OUsZuT/LGbkWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALmPkDyxl5MssZuT/LGbkewAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALmPkAixm5K0sZuT/LGbkoQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALmTkAixm5JMsZuT/LGbkwCxm5AcAAAAAAAAAAAAAAAAAAAAAgAEAAIAB8L+f+QAAkAkAAJAJAACfAQAA4AcAAOAHAADggwAA/gEAAPABAADwIQAA+MP///+H////DwAA/g8AAA==";
Image image = new Image(base64);
RootPanel.get().add(image);
Check these things:
is your base64 data starting with data:${mime};base64,?
is your mime really describing the decoded base64 image format?
Have you tryied to add onLoadHandler to the image object? Something like this:
image.addLoadHandler(new LoadHandler () {
#Override
public void onLoad(LoadEvent event) {
image.setUrl(base64);
}
});
Related
here's the interface:
public interface BitmapCallBackInterface {
void onCallBack(Bitmap bitmap);
}
and here's the method and calling it:
public void downloadImagesFromFireStorage(String imgName, final BitmapCallBackInterface bitmapCallBackInterface) {
StorageReference storageRef = FirebaseStorage.getInstance()
.getReferenceFromUrl("gs://fake-mc-app.appspot.com").child("imgs").child(imgName + ".png");
final long ONE_MEGABYTE = 1024 * 1024;
storageRef.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
#Override
public void onSuccess(byte[] bytes) {
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
bitmapCallBackInterface.onCallBack(bitmap);
}
});
}
Edit
call it:
for (i = 0; i < nameList.size(); i++) {
String couponName = nameList.get(i);
storageHandler.downloadImagesFromFireStorage(imgName, new BitmapCallBackInterface() {
#Override
public void onCallBack(Bitmap bitmap) {
insertImg(couponName, bitmap); // store image into SQLite
}
});
}
getDataFromSQLite();
// and then display Bitmaps to the a list of ImageView
Edit
someone had taught me that the thread will continue after receive callback, so i write a for loop to download all the images from firebase-storage, store them all into SQlite database, then retrieve them out and display to ImageView. But it seems like the thread continues before the image download complete? how can i fix it? Maybe i am misunderstanding what i had learned?
what i exectly want to do is, download several images, after all downloading complete, refresh the listview
First, I hope you are using a CursorAdapter for your listview, and not pulling data from sqlite, to an arraylist, to an ArrayAdapter, etc.
Secondly, you ideally shouldn't be storing listview images as part of the database. You can store firebase links, and then in the adapter, you will request the image content (using an image loading library such as Glide, see below)
In any case, what you need to do is notify the adapter dataSetChanged for every call to onCallBack, after your image is inserted, then the list will update after the image is in sqlite.
If you want to wait for all images to be inserted before you notify the adapter, you can check the inserted image position against nameList.size()
You might also want to consider just using the OnSuccessListener<byte[]> interface for storing bytes into sqlite as a BLOB, not necessarily a Bitmap object. Under that scenario, you don't need that extra interface
However, the encouraged pattern on the Android documentation for image loading in general is to use Glide
Getting Image from Firebase Storage using Glide
I'm using XMLWorker in itextpdf library to convert xHTML to pdf.
In the xHTML content there is some tag with local storage images and images from the Internet.
Eg:
<img src="https://www.w3schools.com/images/w3schools_green.jpg" alt="W3Schools.com" style="width:104px;height:142px;"/>
With the local images, I have implemented ImageProvider to provide the resource root path.
But with these images from the Internet, it cannot be loaded.
I tried to override Image retrieve(String src) method of AbstractImageProvider to load images from the Internet, but I got NetworkOnMainThread exception.
I don't know how to use AsyncTask or any other wars to load online images and return it inside Image retrieve(String src).
I've searched in the Internet and people only use ImageProvider with local images. Any ideas for me?
I don't really understand your question without context. This may be fit with your question.
Create a callback inside your ImageProvider. Then every time AsyncTask (or anything that helps you make a request) gives the response, trigger it.
public class ImageProvider {
private OnImageProviderCallback callback;
public ImageProvider(OnImageProviderCallback callback) {
this.callback = callback;
}
public OnImageProviderCallback getCallback() {
return callback;
}
public void setCallback(OnImageProviderCallback callback) {
this.callback = callback;
}
public interface OnImageProviderCallback {
void onRetrievedImage(Image image);
}
public void retrive() {
new AsyncTask<Void, Void, Image>() {
#Override
protected Image doInBackground(Void... voids) {
// request for image here
If(request.success()) {
return request.getImage();
}else{
// Handle error
return null;
}
}
#Override
protected void onPostExecute(Image image) {
super.onPostExecute(image);
callback.onRetrievedImage(image);
}
}.execute();
}
}
Then in your activity , make it done by calling this
new ImageProvider(new ImageProvider.OnImageProviderCallback() {
#Override
public void onRetrievedImage(Image image) {
// do something with your image
}
});
Until now, I tried to wrap the whole process of conversion from HTML to PDF inside a "big" AsyncTask.
It's work for now, but the code is a bit ugly because it cause code coupling and hard to extend later on for supporting other conversion types.
I want to create an activity in which you can insert/remove/move/connect nodes between each others and based on them to generate a string value that would be later sent through Bluetooth to an other device.
Something like this
And the resulting string should look like:
`"do[i<0-2>]:
{case[i]:
{0:"Hello ",1:"World",2:"!"}
}"
My problem is that I have no idea how to start creating the view where the nodes will be placed and the nodes themselves
I think that the "workspace" should be just a simple empty view where you can pan and zoom in/out
But for the nodes I have no idea where to start because they need to be able to have multiple inputs/outputs... maybe I need to create a custom veiw/component but like i said :( i don't know how to start
Thanks for the help in advance!
EDIT:
I have decided to use Google's Blockly to generate the string, I have customized the block the way I need to generate the string, but I can't figure it out how to get the "code" generated as a string so I can use it later... does anyone has an idea?
Blockly for Android uses a CodeGenerationRequest.CodeGeneratorCallback to pass the code string back to the application.
See this example from the TurtleActivity:
private final CodeGenerationRequest.CodeGeneratorCallback mCodeGeneratorCallback =
new CodeGenerationRequest.CodeGeneratorCallback() {
#Override
public void onFinishCodeGeneration(final String generatedCode) {
// Sample callback.
Log.i(TAG, "generatedCode:\n" + generatedCode);
Toast.makeText(getApplicationContext(), generatedCode,
Toast.LENGTH_LONG).show();
mHandler.post(new Runnable() {
#Override
public void run() {
String encoded = "Turtle.execute("
+ JavascriptUtil.makeJsString(generatedCode) + ")";
mTurtleWebview.loadUrl("javascript:" + encoded);
}
});
}
};
I have one default image and I want to replace the image when the user or the program already selected an image. I have only the basic image reader for displaying the default image.
private static void loadImage()throws Exception{
File image2 = new File("...Example\\blackimage.jpg");
bi = ImageIO.read(image2);
}
You could override methods so
private static void loadImage(String imagePath) throws Exception {
File image2 = new File(imagePath);
bi = ImageIO.read(image2);
}
private static void loadImage() throws Exception {
loadImage("...Example\\blackimage.jpg");
}
This would give you two methods, one to call if you have a image in mind and one for the default image.
If your program already has one selected for a particular user, for example stored in some sort of local storage / database, it can call the first method, however if an image is not found it can call the default no parameter method.
I'm trying to figure out how to make a dynamically generated csv available to a dygraphs JavaScript.
I'm using a wicket behavior to add the dygraph (JavaScript graph) to my markup like shown in the codesample bellow. Right now I've hardcoded it to use a csv file named "dygraph.csv". I want to change this, and instead make dygraph use the values from String csv, how do I achieve this?
Any help help is greatly appreciated.
public class DygraphBehavior extends AbstractBehavior {
private static final long serialVersionUID = -516501274090062937L;
private static final CompressedResourceReference DYGRAPH_JS = new CompressedResourceReference(DygraphBehavior.class, "dygraph-combined.js");
#Override
public void renderHead(IHeaderResponse response) {
response.renderJavascriptReference(DYGRAPH_JS);
}
#Override
public void onRendered(Component component) {
final String id = component.getId();
Response response = component.getResponse();
response.write(JavascriptUtils.SCRIPT_OPEN_TAG);
response.write("new Dygraph(document.getElementById(\""+id+"\"), \"dygraph.csv\", {rollPeriod: 7, showRoller: true, errorBars: true});");
response.write(JavascriptUtils.SCRIPT_CLOSE_TAG);
}
}
public class Dygraph extends WebPage {
public Dygraph() {
String csv = "Date,ms\n20070101,62\n20070102,62";
add(new ResourceLink<File>("csv", new ByteArrayResource("text/csv", csv.getBytes())));
add(new Label("graphdiv").add(new DygraphBehavior()));
}
}
<div>
<h1>Dygraph:</h1>
<div wicket:id="graphdiv" id="graphdiv" style="width:500px; height:300px;"></div>
<a wicket:id="csv" href="#">dl generated csv</a>
</div>
public class Dygraph extends WebPage {
public Dygraph() {
String csv = "Date,ms\n20070101,62\n20070102,62";
ResourceLink<File> link = new ResourceLink<File>("csv", new ByteArrayResource("text/csv", csv.getBytes()));
add( link );
//this is the url that should be passed to the javascript code
CharSequence url = link.urlFor( IResourceListener.INTERFACE );
add(new Label("graphdiv").add(new DygraphBehavior()));
}
}
There are other solutions based on the scope of your resource, maybe a dynamic shared resource would work better (if your graph parameters can simply be passed as url parameters), but this will work.
The JavaScript needs to see the data in some way after the page has been rendered. So you have two options:
Embed the data in the page (say in a hidden div) and then let JavaScript read the data from there as text.
Create a servlet where the JavaScript can download the data from.
The second option means that your page rendering code has to pass the data somehow to the servlet. You can try to put it into the session but then, it will sit there, occupying RAM. Probably not a problem if it's just a little bit of data and you have only a few users. But if that's not true, option #1 is probably better.