Question is how to get the image data in standart base64 type written from a webview to a file (jpeg in my case) on external storage?
Ti.App.addEventListener('app:save_op', function(d) { //listens events fired from js in webview
var base64img = d.url;
var imageBlob = Ti.Utils.base64decode(base64img);
var imageView = Titanium.UI.createImageView({
image:imageBlob,
// top:20,
// width:300,
// height:100
});
self.add(imageView);
if (Ti.Filesystem.isExternalStoragePresent()) {
// var theMap = win1.toImage();
// var file = Titanium.Filesystem.createTempFile(Titanium.Filesystem.resourcesDirectory);
// Ti.API.info('size = ' + file.size);
// file.write(theMap);
fname = new Date().getTime() + '_' + 'out.jpg';
fname2 = new Date().getTime() + '_' + 'o.jpg';
var f = Ti.Filesystem.getFile(Ti.Filesystem.externalStorageDirectory, fname);
var f2 =Ti.Filesystem.getFile(Ti.Filesystem.externalStorageDirectory, fname2);
// f2 = f.read();
// f2.write();
f.write(d.url);
//
//f.write( imageBlob );
// var img = new Image();
// img.src = imageBlob;
f.write(imageView.image);
alert("nativePath = " + f.nativePath);
I implement event listener to catch base64 string of jpeg file from fireevent in a webview then....but it only writes them as plaintext to a file, not an image
}
I have tried a lot of varients to do this: toImage/ blob--->buffer --->file / base64decode.toString....
If you are only trying to save image to the device, you can try :
Titanium.Media.saveToPhotoGallery(imageBlob);
Here is the documentation
Related
I have Cefsharp winforms v.104
I need to save a screenshot of the whole page. This code changes the browser's resolution. I think this is the wrong way.
Could you specify how to save the entire page correctly.
int width = 1024;
int height = 768;
string jsString = "Math.max(document.body.scrollHeight, " +
"document.documentElement.scrollHeight, document.body.offsetHeight, " +
"document.documentElement.offsetHeight, document.body.clientHeight, " +
"document.documentElement.clientHeight);";
JavascriptResponse JSresponse = await chromeBrowser.EvaluateScriptAsync(jsString);
height = Convert.ToInt32(JSresponse.Result);
var client = chromeBrowser.GetDevToolsClient();
await client.Emulation.SetDeviceMetricsOverrideAsync(width, height, 1, true);
await Task.Delay(1000);
await chromeBrowser.CaptureScreenshotAsync().ContinueWith(t => {
using (FileStream fs = new FileStream(#"D:\\" + DateTime.Now.Ticks + ".jpg", FileMode.Create, FileAccess.ReadWrite))
{
byte[] b = t.Result;
fs.Write(b, 0, b.Length);
}
});
thanks amaitland
var contentSize = await chromiumWebBrowser.GetContentSizeAsync();
var viewPort = new DevTools.Page.Viewport
{
Width = contentSize.Width,
Height = contentSize.Height,
};
var data = await chromiumWebBrowser.CaptureScreenshotAsync(viewPort: viewPort, captureBeyondViewport: true);
var screenshotPath = #"D:\\" + DateTime.Now.Ticks + ".jpg";
File.WriteAllBytes(screenshotPath, data);
I'm working on a app that use cordova-plugin-media to record and audio file, and now I want to encode this file to base64 string, for now I can locate the file but when I try to encode it I get this :
"{"$$state":{"status":0}}"
Here is my code
audio.stopRecord();
audio.play();
if(device.platform == "iOS")
{
var path = cordova.file.tempDirectory;
}
else if(device.platform == "Android")
{
var path = cordova.file.externalRootDirectory;
}
var filename = name + extension;
var filepath = path + filename;
console.log(filepath);
console.log(JSON.stringify($cordovaFile.readAsDataURL(path, filename)));
file path : file:///storage/emulated/0/tPUhcxUKhmLUrWK3Qkqhc69OxeEIWyYrhEB0he9OwM0ffmjY2OUh3TLbFTsApdpIpjxyuC2wouyCs6m7uvdOCHCMiw9mbLMGYM25.mp3
Can any one help me with this??
Thanks
readAsDataURL needs a file object, it won't work with a string path.
Give the following code a try, working on iOS and Android
window.resolveLocalFileSystemURL(path, function(fileEntry) {fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function(evt) {
var base64String = evt.target.result;
};
reader.readAsDataURL(file);
});}, function(e){console.log("error:" + JSON.stringify(e));});
I have this below html (angular js based so it may have some angular tags)
https://gist.github.com/sudarshann/668ba8d3dda02da366f59af2bcc3187a
which I am trying to convert to xls export using the below code
var date = new Date();
var fileName = "Resumos " + tabName + " " + date + ".xls";
var fileRaw = document.getElementById(id).innerHTML;
fileRaw = fileRaw.split("↑").join("");
var file = fileRaw.split("↓").join("");
var blob = new Blob([file], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8;"
});
saveAs(blob, fileName);
The result I am get in the Excel file (opened with MS Office 2016)
https://www.dropbox.com/s/yyqowtzebaet7xl/error.jpg?dl=0
This code finally fixed my encoding issues.
var date = new Date();
var sheetName = "BASE DE CONCESSIONÁRIAS " + date;
var fileName = sheetName + ".xls";
var fileRaw = document.getElementById(id).innerHTML;
fileRaw = fileRaw.split("↑").join("");
var file = fileRaw.split("↓").join("");
$log.info("here ", file);
var uri = 'data:application/vnd.ms-excel;base64,'
, template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><?xml version="1.0" encoding="UTF-8" standalone="yes"?><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body>{table}</body></html>'
, base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) }
, format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) }
var toExcel = file;
var ctx = {
worksheet: sheetName || '',
table: toExcel
};
var link = document.createElement('a');
link.download = fileName;
link.href = uri + base64(format(template, ctx));
link.click();
PS: I am still not sure why this fixed the issue or how this is different. It will be nice if some one can explain me on how and why this works and not the code in the question
I'm using (ngImgCrop) to crop an image and then upload the cropped image to server using (angular-file-upload).
I can get the $dataURI from the "on-change" option in ngImgCrop. But I need a File instace to call $upload.
How can I get the File instance of the cropped image in order to upload :
$scope.upload = $upload.upload({
url: '/api/fileupload',
file: [**file cropped here**]
}).progress(function (evt) {
//
}).success(function (data, status, headers, config) {
//
});
I guess you'll find a proper answer in this method. I found it in Github, in the angular-file-upload issues page (https://github.com/nervgh/angular-file-upload/issues/208):
/**
* Converts data uri to Blob. Necessary for uploading.
* #see
* http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata
* #param {String} dataURI
* #return {Blob}
*/
var dataURItoBlob = function(dataURI) {
var binary = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: mimeString});
};
You should be able to get a file instance doing something like this:
var blob = dataURItoBlob($scope.croppedImage);
I don't know if it works in the good way, but it seems.
try something like:
var uploader = $scope.uploader = new FileUploader({
url: '/saveImagePath',
autoUpload: false
});
angular.element(document.querySelector('#fileInput')).on('change',handleFileSelect);
var handleFileSelect=function(evt) {
var file=evt.currentTarget.files[0];
var reader = new FileReader();
reader.onload = function (evt) {
$scope.$apply(function($scope){
$scope.myImage=evt.target.result;
});
};
reader.readAsDataURL(file);
};
the uploader doesn't support base64 images so you'll need to convert the cropped image from base64 to blob
function base64ToBlob(base64Data, contentType) {
contentType = contentType || '';
var sliceSize = 1024;
var byteCharacters = atob(base64Data);
var bytesLength = byteCharacters.length;
var slicesCount = Math.ceil(bytesLength / sliceSize);
var byteArrays = new Array(slicesCount);
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
var begin = sliceIndex * sliceSize;
var end = Math.min(begin + sliceSize, bytesLength);
var bytes = new Array(end - begin);
for (var offset = begin, i = 0 ; offset < end; ++i, ++offset) {
bytes[i] = byteCharacters[offset].charCodeAt(0);
}
byteArrays[sliceIndex] = new Uint8Array(bytes);
}
return new Blob(byteArrays, { type: contentType });
}
you have to manually attach the files to the queue like this:
$scope.submit = function () {
var file = base64ToBlob($scope.currentPortfolio.croppedImage.replace('data:image/png;base64,',''), 'image/jpeg');
uploader.addToQueue(file);
uploader.uploadAll();
};
in the server side, you got two types of files one posted as HTML file and another un base64 which is the cropped image.
The application I'm working uses an API developed by another team. I'm working on Titanium 2.1.2 and I'm trying to upload a photo using said API. I'm using Appcelerator's HTTPClient to make the request. Here's my code:
var url = 'http://api.veramiko.com/albums/' + album.veramiko_id + '/photos';
var photo = imageView.toBlob();
var args = { //parameters sent to post photo
file : photo,
description : descriptionText
};
var client = Ti.Network.createHTTPClient({
onload : function(e){
Ti.API.info(this.responseText); //Print the result
},
onerror : function(e){
Ti.API.error(this.responseText); //Print the result
},
timeout : 60000
});
client.open('POST', url);
client.setRequestHeader('Authorization', 'Bearer ' + token);
client.setRequestHeader('Content-type', "multipart/form-data");
client.send(args);
Token is a variable we use to authorize any requests made to the server. I thought that by only converting the image from the ImageView into Blob would be enough to send the photo, but the photo isn't uploaded. The post is created with the description but the photo isn't sent properly.
Do I need to add something else? Is it right to send the photo as a Blob?
EDIT: I read this link and I tried the following with no result:
var url = 'http://api.veramiko.com/albums/' + album.veramiko_id + '/photos';
var boundary = '-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
var photo = imageView.toBlob();
var args = {
file : photo,
description : descriptionText.value
};
var contentDisposition = "--" + boundary + "\r\n";
contentDisposition += "Content-Disposition: form-data; name=\"file\";";
contentDisposition += "filename=\"" + imageView.image + "\"\r\n\";";
contentDisposition += "Content-Type: application/octet-stream\r\n\r\n";
var fullContent = contentDisposition + photo + "\r\n--" + boundary + "--";
alert(JSON.stringify(args));
var token = JSON.parse(Ti.App.Properties.getString('loggedUser', 'No existe')).networks[0].token;
var client = Ti.Network.createHTTPClient({
onload : function(e){
Ti.API.info(this.responseText); //Print the result
},
onerror : function(e){
Ti.API.error(this.responseText); //Print the result
},
timeout : 60000
});
client.open('POST', url);
client.setRequestHeader('Authorization', 'Bearer ' + token);
client.setRequestHeader('Content-Type', "multipart/form-data; boundary=\"" + boundary + "\"");
client.setRequestHeader('Connection', 'close');
client.send(fullContent);
I tried to wrap the file with a Content-Disposition and Content-Type header with no result.
I finally found a way to solve this. Please refer to the following link.
This is how my code looked in the end:
// I put the contents of my image into a variable
var f = imageHolder.toImage();
// I create a random name for the image
var tmpName = (new Date()).getTime().toString() + '.png';
// I create a folder where I will store the photo temporally
var g = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'picturesToUpload');
if (!g.exists()) {
// If the directory doesn't exist, make it
g.createDirectory();
};
var photo = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'picturesToUpload', tmpName);
// write the contents of the image into the file
photo.write(f);
// I create my url with the albumId where I'll upload the picture
var url = 'http://api.veramiko.com/albums/' + albumId + '/photos';
var args = {
file : photo.read(), // I read the contents of the file
description : ''
}
var token = JSON.parse(Ti.App.Properties.getString('loggedUser', 'No existe')).networks[0].token;
var client = Ti.Network.createHTTPClient({
onload : function(e){
Ti.API.info('Info received from the uploading: ' + this.responseText);
},
onerror : function(e){
Ti.API.debug('Error: ' + this.responseText);
},
timeout : 60000
});
client.open('POST', url);
// these headers are important
client.setRequestHeader('enctype', 'multipart/form-data');
client.setRequestHeader('Content-Type', 'image/png');
client.setRequestHeader('Authorization', 'Bearer ' + token);
client.send(args);
Hope this info helps more people.
First of all you Clear what is you API Parameter. and where you want to use TOKEN.
var imageView = Ti.UI.createImageView({
backgroundImage : "image.png",
});
var url = 'http://api.veramiko.com/albums/' + album.veramiko_id + '/photos';
var args = { //parameters sent to post photo
file : imageView.backgroundImage,
description : descriptionText,
token : "Token",
};
var client = Ti.Network.createHTTPClient({
onload : function(e){
Ti.API.info(this.responseText); //Print the result
},
onerror : function(e){
Ti.API.error(this.responseText); //Print the result
},
timeout : 60000
});
client.open('POST', url);
client.setRequestHeader("Content-type","multipart/form-data");
client.setRequestHeader("Content-length", args.length);
client.send(args);
Try This, I thought this is working for you...
I found this tutorial, that covers on how to build an uploader.
Titanium Mobile: Build an Image Uploader
You case use this code to upload a file in form-data :
var baseurlAPI = "YOUR API BASEURL HERE";
var file = Ti.Filesystem.getFile(pathToFile);
if(file.exists()){
var xhr = Ti.Network.createHTTPClient({
onload: function(e) {
Ti.API.log('success '+this.responseText);
},
onerror: function(e) {
Ti.API.error(this.responseText);
},
timeout : -1
});
xhr.open('POST', baseurlAPI);
xhr.send({
file: file
});
}else{
console.log('didnt exist ' + file.nativePath);
}