I'm working on a WinJS Windows Metro application and on one of my pages I'm getting a URL to an image to display as a background. I can get that working just fine by using url(the URL of the image) and setting that as the style.backgroundImage.
I need to use that same image on a linked page, but that means I have to make another HTTP request, which I'm trying to avoid. I looked into alternatives and found LocalFolder as an option. The only issue is I don't know how to access the file and set it as a background.
Is that the right way to go about caching data to reduce webcalls?
Here's the code I'm using:
function saveBackground(url) {
localFolder.createFileAsync("background.jpg", Windows.Storage.CreationCollisionOption.replaceExisting).then(function (newFile) {
var uri = Windows.Foundation.Uri(url);
var downloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
var promise = downloader.createDownload(uri, newFile);
promise.startAsync().then(function () {
//set background here.
var wrapper = document.getElementById("wrapper").style;
localFolder.getFileAsync("background.jpg").then(function (image) {
console.log(image.path);
var path = image.path.split("");
var newLocation = [];
//This is just to make the backslashes work out for the url()
for (var i = 0; i < path.length; i++) {
if (path[i] != '\\') {
newLocation.push(path[i]);
} else {
newLocation.push('\\\\');
}
}
console.log(newLocation);
var newPath = newLocation.join("");
var target = "url(" + newPath + ")";
wrapper.backgroundImage = target;
console.log(wrapper.backgroundImage);
wrapper.backgroundSize = "cover";
});
});
});
}
It depends on which kind of image you want to transfer and how many of these. If there is only one image and not an heavy one (<5Mo approximately) I suggest you to use WinJS.xhr which allows you to download datas and more important it downloads the data as soon as its called.
The BackgroundTransfer should be used for big datas such as videos, musics, large images.
Concerning the caching of your image yes you can do it of course with the local folder (and you should do it this way).
You should take a look to this series of article made by David Catuhe which are really great
http://blogs.msdn.com/b/eternalcoding/archive/2012/06/15/how-to-cook-a-complete-windows-8-application-with-html5-css3-and-javascript-in-a-week-day-0.aspx
Hope this help.
Related
I'm a web developer from japan.
This is first question on stack over flow.
I'm creating a simple music Web application now.
making a music system program is a completely beginner, so I am struggling to implement it.
As a result of various investigations, I noticed that using the Web Audio API was the best choice,
so, I decided to use it.
▼ What I want to achieve
Multiple Wav files load with the Web audio API can be grouped into one Wav file &To be able to download from the browser.
For example, load the multiple wav file like guitar, drum and piano, and
edit it on the browser, and finally output it as one Wav file.
Then we can download that edited wav file from the browser and we are able to play itunes.
▼ Question
Is it possible to achieve this requirements by just using web audio api ?
or we need to use another Library ?
I checked Record.js on github but development has stopped about 2 ~ 3 years and has many issues and I can not get support. so I decided not to use it.
and also I checked similar issue Web audio API: scheduling sounds and exporting the mix
Since the information is old, I do not know if I can still use it
thanks.
Hi and welcome to Stack Overflow!
Is it possible to achieve this just using the web audio api?
In terms of merging/mixing the files together this is perfectly achievable! This article goes through many (if not all) of the steps you will need to carry out the task you suggested.
Each file you want to upload can be loaded into an AudioBufferSource (examples explained in that article linked before) Example setting up a buffer source once the audio data has been loaded in:
play: function (data, callback) {
// create audio node and play buffer
var me = this,
source = this.context.createBufferSource(),
gainNode = this.context.createGain();
if (!source.start) { source.start = source.noteOn; }
if (!source.stop) { source.stop = source.noteOff; }
source.connect(gainNode);
gainNode.connect(this.context.destination);
source.buffer = data;
source.loop = true;
source.startTime = this.context.currentTime; // important for later!
source.start(0);
return source;
}
There are then also specific nodes already designed for your mixing purposes like the ChannelMergerNode (combines multiple mono channels into a new channel buffer). This is if you don't want to deal with the signal processing yourself in javascript but will be faster using the Web Audio objects since they are native compiled code already within the browser.
Following that complete guide sent before, there are also options to export the file (as a .wav in the demo case) using the following code :
var rate = 22050;
function exportWAV(type, before, after){
if (!before) { before = 0; }
if (!after) { after = 0; }
var channel = 0,
buffers = [];
for (channel = 0; channel < numChannels; channel++){
buffers.push(mergeBuffers(recBuffers[channel], recLength));
}
var i = 0,
offset = 0,
newbuffers = [];
for (channel = 0; channel < numChannels; channel += 1) {
offset = 0;
newbuffers[channel] = new Float32Array(before + recLength + after);
if (before > 0) {
for (i = 0; i < before; i += 1) {
newbuffers[channel].set([0], offset);
offset += 1;
}
}
newbuffers[channel].set(buffers[channel], offset);
offset += buffers[channel].length;
if (after > 0) {
for (i = 0; i < after; i += 1) {
newbuffers[channel].set([0], offset);
offset += 1;
}
}
}
if (numChannels === 2){
var interleaved = interleave(newbuffers[0], newbuffers[1]);
} else {
var interleaved = newbuffers[0];
}
var downsampledBuffer = downsampleBuffer(interleaved, rate);
var dataview = encodeWAV(downsampledBuffer, rate);
var audioBlob = new Blob([dataview], { type: type });
this.postMessage(audioBlob);
}
So I think Web-Audio has everything you could want for this purpose! However could be challenging depending on your web development experience, but its a skill definately worth learning!
Do we need to use another library?
If you can I think it's definately worth trying it with Web-Audio, as you'll almost definately get the best speeds for processing, but there are other libraries such as Pizzicato.js just to name one. I'm sure you will find plenty others.
I'm creating a NativeScript application that is supposed to work on both Android and iOS. I need to display some images that are in a S3 bucket.
As I want to show some progress indicator while the image is being downloaded I think I should download the image locally instead of just setting the source property of the Image component. What is the best thing to do?
After a little bit more research I found this sample https://github.com/telerik/nativescript-sample-cuteness/blob/master/nativescript-sample-cuteness/ and it has plenty of images downloaded from the Internet.
What I used is a module called image-cache that solves exactly this problem.
Here is what I used more precisely:
var imageSourceModule = require("image-source");
var imageCache = require("ui/image-cache");
var cache = new imageCache.Cache();
var defaultImageSource = imageSourceModule.fromFile("~/app/res/loading.gif");
var defaultNotFoundImageSource = imageSourceModule.fromFile("~/app/res/no-image.png");
cache.invalid = defaultNotFoundImageSource;
cache.placeholder = defaultImageSource;
cache.maxRequests = 5;
function displayImage(viewModel, url, propertyName) {
var source = cache.get(url);
propertyName = propertyName || "image";
if (source) {
viewModel.set(propertyName, source);
} else {
viewModel.set(propertyName, defaultImageSource);
cache.push({
key: url,
url: url,
completed: function (result, key) {
if (key === url) {
viewModel.set(propertyName, result);
}
}
});
}
}
If there is a better solution, I would be happy to learn about it.
There is plugin available called nativescript-web-image-cache. As per their npm page:
A minimalistic NativeScript plugin that wraps just the caching
functionality of SDWebImageCache library for iOS and Facebook Fresco
for android. Supports local Images.
You can also check if image is loading, e.g. Get the reference to the WebImage view by using angular template variable references and #ViewChild decorator and check the isLoading property (same as that of NativeScript Image isLoading property).
I want to create an image upload widget that resizes (scales) images to a low res (say 640x640). I want to then upload these resized images to the server. Mainly to prevent huge file uploads.
What is the best way to implement it? I'm using JQuery and Django.
Browser support for this will be limited although you can mitigate this by writing Flash and Silverlight shims that do the same thing. I've seen a few html5 examples of how to do this as well.
Plupload is a nice tool for managing this and gives you all the shims and uploaders detailed above.
http://www.plupload.com/example_all_runtimes.php
if you look at the example embed code there is a resize object as part of the config in which you can define the parameters described in your post
Use Canvas and HTML5.
It's pretty simple, just use a FileReader (will not work on iOS/iPhone since they don't have files at a user level) to open on the File/File list you get back from an input type file element:
function fileSelectHandler(e) {
files = e.target.files;
var len = files.length;
for(var filei = 0; filei < len; filei += 1) {
var aFile = files[filei];
var fileReader = new FileReader();
fileReader.onload = (function (theFile) {
return function(e) {
if(e.target.result != null && e.target.result != undefined) {
var imge = new Image();
imge.src = e.target.result;
imageDataURLs[theFile.name] = imge;
imge.onload = (function () {
return function(e) {
draggables[0] = new Draggable(g3,imge);
draggableFlow.launch();
};
})();
}
};
})(aFile);
fileReader.readAsDataURL(aFile);
} // for next file
};
Then write the image to a canvas element and enable the user to drag it around and crop it. When they're happy grab the data from the canvas using CanvasRenderingContext2D.getImageData, and send that base64 string to the server in XHR.
I have asked this question also on the appcelerator forum, but as I find I often get better answers from you lovely people here on stackoverflow I am also asking it here just incase anyone can spread some light.
I have created a downloadQueue of urls and am using it to download files with the httpclient. Each file in the downloadQueue is is sent the the httpclient one at a time, with the next download being initiated only after the previous has been completed.
When I start the download, it seems to be working correctly and manages to download several files before it it simply freezes and I get an "out of memory" error in the DDMS error log.
I tried implementing suggestions found in other posts a sample of which are:
[http://developer.appcelerator.com/question/28911/httpclient-leaks-easily-or-can-we-have-a-close-method#answer-104241][1]
[http://developer.appcelerator.com/question/35041/large-file-download-on-mobile][2]
[http://developer.appcelerator.com/question/120129/httpclient-and-setfile][3]
[http://developer.appcelerator.com/question/95521/httpclient---save-response-directly-to-file][4]
I tried all of the following:
- moving larger file downloads directly form the nativepath rather then simply saving to file in order to insure that tmp files are not kept longer then necessary.
using the undocument setFile method of the httpclient. (This stopped my code dead without any error message, and as it is undocumented I have no idea if it was ever implemented on android anyway)
-using a settimeout in httplient.onload after the file has been download to pause for 1 second before requesting the next file (I have no idea how this would help, but I am clutching a straws now)
Below is the relevant parts of my code (which is complete except for the GetFileUrls functions which I excluded for simplicity sake as all this function does is return an array of URLs).
Can anyone spot anything that might be causing my memory issue. Does anyone have any ideas as I have tried everthing I can think of? (HELP!)
var count = 0;
var downloadQueue = [];
var rootDir = Ti.Filesystem.getExternalStorageDirectory();
downloadQueue = GetFileUrls(); /* this function is not included in order to keep my post as short as possible, bu it returns an array of urls */
DownloadFile(downloadQueue[count]);
var downloader = Ti.Network.createHTTPClient({timeout:10000});
downloader.onerror = function(){
Ti.API.info(this.responseData);
}
downloader.onload = function(){
SaveFile(this.folderName, this.fileName, this.responseData);
count += 1;
setTimeout( function(){ DownloadFile(); }, 1000);
}
function DownloadFile(){
if (count < downloadQueue.length){
var fileUrl = downloadQueue[count];
var fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);
downloader.fileName = fileName;
downloader.folderName = rootDir;
downloader.open('GET', fileUrl);
downloader.send();
}
}
function SaveFile(foldername, filename, response){
if (response.type == 1){
var f = Ti.Filesystem.getFile(response.nativePath);
var dest = Ti.Filesystem.getFile(foldername, filename);
if (dest.exists()){
dest.deleteFile();
}
f.move(dest.nativePath);
}else{
var dest = Ti.Filesystem.getFile(foldername, filename);
dest.write(response);
}
}
try to use events instead of the nested recursion that you are using. Android does not seem to like that too much
The question says it all: how to get a remotely hosted image into a string. I will later use XMLHTTPPost to upload the content. This is javascript question, for those who don't read tag line.
#Madmartigan: the script itself is executed in rather odd manner: user uses javascript: to append the script from the remove host. (this gives access to the user cookie session, which we need in order to proceed) This generates form, giving user ability to setup some texts. (this is easy bit) When user clicks upload the script must get an image hosted on remote host. I am trying to get the image from the remote host as a string and then use something like the function below to convert it to binary. So, how do I do that?
function toBin(str){
var st,i,j,d;
var arr = [];
var len = str.length;
for (i = 1; i<=len; i++){
//reverse so its like a stack
d = str.charCodeAt(len-i);
for (j = 0; j < 8; j++) {
st = d%2 == '0' ? "class='zero'" : ""
arr.push(d%2);
d = Math.floor(d/2);
}
}
//reverse all bits again.
return arr.reverse().join("");
}
I should mention, that I managed to find things like:
var reader = new FileReader();
reader.onload = function() {
previewImage.src = reader.result;
}
reader.readAsDataURL(myFile);
However, they are very browser dependent and therefore not very useful.
I am trying to avoid using base64 because of the redundant size increase.
EDIT: take a look here. Take should help you: http://www.nihilogic.dk/labs/exif/ or maybe here: http://jsfromhell.com/classes/binary-parser the only way to store binary data into string in javascript context is to use base64/base128 encoding. But I never tried it myself to do that in case of a image. There are many JavaScript base encoder/decoder out. Hope this helps you.