How can i create a simple vala Gtk code of an application to open images of a folder and display one at a time ?
I have to create a Vala application to open a folder of images and display a single image at a time.
I have a Gtk.Stack to show only one Image received for a Gtk.FileChooserDialog, but i can't do the Gtk.Filechooser.Dialog to receive more elements and display them.
Thanks
There are 2 solutions:
You want to select multiple files form the same folder: Then just do chooser.select_multiple = true; and you'll get a SList of file URIs via chooser.get_uris()
You need to just select the folder: Then create your FileChooserDialog with the proper action (Gtk.FileChooserAction.SELECT_FOLDER):
var chooser = new Gtk.FileChooserDialog (
"Pick the folder to load the images", this,
Gtk.FileChooserAction.SELECT_FOLDER,
"_Cancel",
Gtk.ResponseType.CANCEL,
"_Open",
Gtk.ResponseType.ACCEPT);
And when you get the proper Folder:
if (chooser.run () == Gtk.ResponseType.ACCEPT) {
var folder = File.new_from_uri (chooser.get_uri ());
if (folder.query_exists() && folder.query_file_type (0) == FileType.DIRECTORY) {
// It's a directory and exists, so enumerate the children and do you stuff
}
}
chooser.close ();
Related
I need to extract some random images from gallery without the picker option. Please be clear that I don't want to open picker for this, just extract images if user tapped the button.
You could use dart:io to get the files in a directory and display one of the image files in the directory.
import 'dart:io' as io;
var files = io.Directory("/storage/emulated/0/DCIM/Camera").listSync();
final _random = new math.Random();
var idx= _random.nextInt(files.length) ;
var file = files[idx];
//TODO display the file.
I would like to do image annotation for my Ionic Application. So the flow of the app would be using the camera plugin to take a picture and use FabricJs to draw on the image then save the file.
I hit the roadblock when I am trying to save or overwrite the file. Apparently the source "http://localhost:8080/file/data/user/0/***/files/1547183479807.png" file does not update.
The flow of the app
1) Take picture with #ionic-native/camera
2) Copy the file to a local directory
3) Use this.win.Ionic.WebView.convertFileSrc to convert the file name to "http://localhost:8080/file/data/user/0/***/files/1547183479807.png"
4) Push to another page to access the canvas
5) Use the link to setBackground to my canvas (FabricJs)
6) Draw on the image (Manually)
7) Save the file via overwriting the existing file but nothing works from here on.
I tried to
- overwrite with writeFile & writeExisitingFile, did not work.
- removeFile and writeFile and did not work.
- tried converting to ArrayBuffer rather than Blob and did not work
- tried creating another new file, did not work too (it seems like after I push to a new page, all the file functions does not affect the files)
- tried using native cordova but did not work too.
- delete that same files twice, (first time I did not get an error but the second time I got an error saying "File Does not exist" but when I view the source, the file is also there and appearing in my thumbnail on my App.
private copyFileToLocalDir(namePath, currentName, newFileName,id,index) {
this.file.copyFile(namePath, currentName, this.file.dataDirectory, newFileName).then(success => {
const keys = id.split('-');
let filename = this.file.dataDirectory + newFileName;
this.fp = this.win.Ionic.WebView.convertFileSrc(filename) ;
this.navCtrl.push(AnnotationsPage, {
filepath: this.fp,
filename: newFileName
});
this.presentToast("Image Successfully Added",'middle');
}, error => {
this.presentToast('Error while storing file.','middle');
});
}
Annotation.ts
savePicture() {
let image = this.canvas.toDataURL({
format: 'png'
});
this.saveBase64(image);
}
public saveBase64(base64:string):Promise<string>{
return new Promise((resolve, reject)=>{
var realData = base64.split(",")[1]
let blob=this.b64toBlob(realData,"image/png")
this.file.writeFile(this.file.dataDirectory,this.filename,blob,{replace:true})
// this.file.writeExistingFile(this.file.dataDirectory,this.filename, blob)
.then((val)=>{
console.log('Write Info',val)
let fp = this.win.Ionic.WebView.convertFileSrc(this.file.dataDirectory+this.filename) ;
})
.catch((err)=>{
console.log('error writing blob')
console.log(err);
// reject(err)
})
})
}
b64toBlob(b64Data, contentType) {
contentType = contentType || '';
var sliceSize = 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
I check the base64 file, it is working fine (Throw the data to an online converter and it display the picture.
After the function "copyFileToLocalDir", it seems like I am unable to modify the files store in the local directory.
Thanks in advance. Feel free to ask me more question. 7 hours and no result.
Update on the testing, I am doing.
Did File.readAsDataUrl and as expected the file file:///data/user/0/*/files/1547231914843.png updated from the old image to the new edited. (Tested the base64 on some online converter) but it still does not reflect on the source http://localhost:8080/file/data/user/0/***/files/1547231914843.png
Thanks to all those who read through.
After tons of testing, I found out that Ionic Webview's files, will not be updated unless you recall them again (Kind of like a cache and apparently there is no way to reset or flush the cache).
So in my case, I would need to remove the image from the webview and call it out again then it will go back to retrieve again or create another file with another file name and display it.
I'm trying to use the share() method, including an image, but I'm having trouble supplying the proper path to the image. Where should I put the image file, and what is the path (putting in the default package and trying "jar:///myimage.png" didn't work), and why is this not documented clearly?
image can be stored in storage which is following path for window
C:\Users\userName.cn1
and the image can be read by using following codes
InputStream is = Storage.getInstance().createInputStream("tizbn.JPG");
EncodedImage i = EncodedImage.create(is, is.available());
Loading image from default folder
Image i =EncodedImage.create("/tizbn.png");
Loading image From Theme
EncodedImage current = (EncodedImage) fetchResourceFile().getImage("tizbn.png");
The share API works with https://www.codenameone.com/javadoc/com/codename1/io/FileSystemStorage.html[FileSystemStorage] and not with https://www.codenameone.com/javadoc/com/codename1/io/Storage.html[Storage].
You need to save the file into a file system path which is always an absolute path, we recommend using the app home to store files. There is a sample in the developer guide section on the ShareButton covering this:
Form hi = new Form("ShareButton");
ShareButton sb = new ShareButton();
sb.setText("Share Screenshot");
hi.add(sb);
Image screenshot = Image.createImage(hi.getWidth(), hi.getHeight());
hi.revalidate();
hi.setVisible(true);
hi.paintComponent(screenshot.getGraphics(), true);
String imageFile = FileSystemStorage.getInstance().getAppHomePath() + "screenshot.png";
try(OutputStream os = FileSystemStorage.getInstance().openOutputStream(imageFile)) {
ImageIO.getImageIO().save(screenshot, os, ImageIO.FORMAT_PNG, 1);
} catch(IOException err) {
Log.e(err);
}
sb.setImageToShare(imageFile, "image/png");
On my Google Site I've inserted an Apps Script Gadget (by pasting the URL of an Apps Script that I published as a service). This Apps Script allows the user to enter a value (their 'Blow Number') and view the corresponding data (based on API calls to my Google Fusion tables).
Right now, the script returns 3 hyperlinks:
Click here for a table of Blow Number 1
Click here for a chart of Blow Number 1
Click here for a map of Blow Number 1
This is because my script function getblowdetails has 3 app.createAnchor variables. Instead of having the script return 3 hyperlinks (that the user has to click on and view the resulting URL in a new window), I would like for the script to automatically invoke the 3 URLs and display the table, chart, and map in panels on the same page.
So the user would enter their Blow Number and press enter. They would then view the table, chart, and map directly below the text box on the same web page.
Please see the Code that I've included below and advise...Thanks for the help- I'm an apps-script novice so a thorough and understand-able response is greatly appreciated!
Code
Note: I've removed the URLs from the createAnchor variables because I'm only allowed to include 2 links in the post, but you can see them by going to www.OnSiteBAC.com/ViewMyBlows and entering Blow Number = 1...then click on the hyperlinks.
function doGet() {
var app = UiApp.createApplication();
// Create input boxes, buttons, labels, and links
var textBoxA = app.createTextBox().setId('textBoxA').setName('textBoxA').setFocus(true);
var buttonA = app.createButton('Get Blow Details').setEnabled(false);
var label = app.createLabel('Please enter your Blow Number here');
var link = app.createAnchor('where can I find my Blow Number?', 'http://www.onsitebac.com');
// Create a handler to call the getblowdetails function.
// A validation is added to this handler so that it will only invoke 'getblowdetails' if textBoxA contains a number
var handler = app.createServerClickHandler('getblowdetails').validateNumber(textBoxA).addCallbackElement(textBoxA);
// Create a handler to enable the button if all input is legal
var onValidInput = app.createClientHandler().validateNumber(textBoxA).forTargets(buttonA).setEnabled(true).forTargets(label, link).setVisible(false);
// Create a handler to mark invalid input in textBoxA and disable the button
var onInvalidInput1 = app.createClientHandler().validateNotNumber(textBoxA).forTargets(buttonA).setEnabled(false).forTargets(textBoxA).setStyleAttribute("color", "red").forTargets(label, link).setVisible(true);
// Create a handler to mark the input in textBoxA as valid
var onValidInput1 = app.createClientHandler().validateNumber(textBoxA).forTargets(textBoxA).setStyleAttribute("color", "black");
// only fire ServerHandler for onKeyUp if it passes validation
var textBoxHandler = app.createServerHandler('textBoxHandlerFunction');
// Add all the handlers to be called when the user types in the text boxes
textBoxHandler.addCallbackElement(textBoxA);
textBoxA.addKeyUpHandler(onInvalidInput1);
textBoxA.addKeyUpHandler(onValidInput1);
textBoxA.addKeyUpHandler(onValidInput);
textBoxA.addKeyUpHandler(textBoxHandler);
buttonA.addClickHandler(handler);
app.add(textBoxA);
app.add(buttonA);
app.add(label);
app.add(link);
return app;
}
function textBoxHandlerFunction(e) {
var app = UiApp.getActiveApplication();
if (e.parameter.keyCode == 13)
{
app = getblowdetails(e);
}
return app;
}
function getblowdetails(e) {
var app = UiApp.getActiveApplication();
var panel2 = app.createVerticalPanel();
var link2 = app.createAnchor ().setStyleAttribute("color", "green");
var panel3 = app.createVerticalPanel();
var link3 = app.createAnchor ();
var panel4 = app.createVerticalPanel();
var link4 = app.createAnchor ();
panel3.add(link3);
app.add(panel3);
panel4.add(link4);
app.add(panel4);
return app;
}
I don't think you'll be able to actually download the result and show it. So, there's no easy solution.
But you can build that table and chart on Apps Script easily (assuming you can already fetch the info from tables using its API).
The last issue is the map. On Apps Script you can only create static maps, meaning, an image. You can add custom markers and polygons, set the zoom, etc. But in the end it's a photo. The user will not be able to drag it around or use the map as an embedded google map as one would expect.
When a document does not have any modal dialog window messages, app.activeDocument.close(SaveOptions.no) works fine.
However, I have some InDesign documents that do have such windows appear, showing error messages about links that need to be updated, or incorrect styles. The above statement won't work in this case, as the windows prevent the script from accessing the document.
So, is there a way to iterate through all of the modal-dialogs in the active document? Here is what I have tried so far, which is not working:
if(xmlFile == "")
{
//alert("There is no linked XML file in this document,\n\ttry a different document.");
for(var i = 0; i < app.activeDocument.Windows.length; i++)
{
app.activeDocument.Windows[i].close();
}
app.activeDocument.close(SaveOptions.no);
exit();
}
Ok, so the "user interaction level" of the application needs to be changed to "NEVER_INTERACT" to ignore all modal dialog windows. Here is the modified code, which is now working:
if(xmlFile == "")
{
alert("There is no linked XML file in this document,\n\ttry a different document.");
// the original interaction and warning settings of the application
var oldInteractionPrefs = app.scriptPreferences.userInteractionLevel;
// prevent interaction and warnings from interrupting script
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;
// close the active document without saving
app.activeDocument.close(SaveOptions.no);
// reset interactions to original settings
app.scriptPreferences.userInteractionLevel = oldInteractionPrefs;
exit();
}
Did you try it ?
app.activeDocument.windows.everyItem.close(SaveOptions.no);