On line 140 of image-source-android.js this.android.compress(targetFormat, quality, base64Stream);
I'm getting this error this.android.compress is not a function
. I'm using the nativescript-camera to take a picture and then save it to base64 string. Also, the image is saving to my photos even when I set saveToGallery: false
.
Here my code:
cameraModule.takePicture({
width: 1280, height: 720, keepAspectRatio: false, saveToGallery: false
}).then(function (imageAsset) {
console.log("Result is an image asset instance");
viewModel.set("BoardingPassSource", imageAsset);
var image = ImageSourceModule.fromNativeSource(imageAsset);
var base64 = image.toBase64String("jpeg");
// var image = new imageModule.Image();
// image.imageSource = imageAsset;
// image.toBase64String("jpeg");
viewModel.set("base64String", base64);
}).catch(function (err) {
console.log("Error -> " + err.message);
});
package.json
{
"description": "NativeScript Application",
"license": "SEE LICENSE IN <your-license-filename>",
"readme": "NativeScript Application",
"repository": "<fill-your-repository-here>",
"nativescript": {
"id": "org.nativescript.****",
"tns-android": {
"version": "2.5.0"
}
},
"dependencies": {
"nativescript-background-http": "^2.4.2",
"nativescript-barcodescanner": "^2.3.3",
"nativescript-camera": "0.0.8",
"nativescript-drawingpad": "^1.1.2",
"nativescript-drop-down": "^1.5.1",
"nativescript-loading-indicator": "^2.2.2",
"nativescript-telerik-ui": "^1.5.1",
"nativescript-theme-core": "^1.0.2",
"nativescript-timedatepicker": "^1.1.0",
"tns-core-modules": "^2.5.0"
},
"devDependencies": {
"babel-traverse": "6.21.0",
"babel-types": "6.21.0",
"babylon": "6.14.1",
"lazy": "1.0.11"
}
}
Hi @emmanuel128
I can confirm this issue is reproducible with tns-core-modules 2.5.0. We will get back at you in this thread once we have applicable solution and/or fix.
Test application demonstrating the issue can be found here.
Throwing at this line in tns-core-modules as this.android
is ImageAsset and not android.graphics.Bitmap
Hi @NickIliev
Thanks for trying to fix this! If this is a problem with tns-core-modules 2.5.0, I'm able to convert the result of nativescript-camera
to a base64 string? That is the biggest challenge I'm having right now :/
Update:
I use the same instruction but with the built-in camera module and it works perfectly, but this module is now deprecated.
Tested with _modules30_ and works as expected
How can I test it?
@NickIliev : this issue is resolved..??
Hey @emmanuel128 , @pap5508
The issue is resolved with our next release 3.0 - however, it is a major version release coming with some breaking changes so we are still working on it. More about the upcoming release can be found here.
@NickIliev : Is there any alternative to convert it into Base64 string.. because I would like to convert to base64 and send Image..
I am stuck with this Base64 encoding issue on iOS.. I am not able to go further.
when Nativescript releasing 3.0 ?
I used the nativescript-camera
and nativescript-imagepicker
to take a picture, save it and convert it to base 64. I hope it helps. If anyone has another workaround please let me know.
// nativescript-camera
cameraModule.requestPermissions();
cameraModule.takePicture({
width: 1280, height: 720, keepAspectRatio: false, saveToGallery: true
}).then(function (imageAsset) {
console.log("Result is an image asset instance");
var context = imagepicker.create({
mode: "single"
});
context
.authorize()
.then(function() {
return context.present();
})
.then(function(selection) {
console.log("Selection done:");
selection.forEach(function(selected) {
selected.getImage().then(res =>{
var d = new Date();
_photoDateTime = d.getFullYear()+"-"+(d.getMonth()+1)+"-"+d.getDate()+" "+
d.getHours()+":"+d.getMinutes()+":"+d.getSeconds();
viewModel.set("PhotoDateTime", _photoDateTime);
viewModel.set("BoardingPassSource", res);
viewModel.set("base64String", res.toBase64String("png"));
console.log("image selected");
});
});
}).catch(function (e) {
console.log(e);
});
}).catch(function (err) {
console.log("Error -> " + err.message);
});
@emmanuel128 : One more Question on Which I required your guidance..
Are you using any image compression library or tool.. Because in my Chat application.. Load all chat containing base64 string and convert in into ImageSource and set it to Image takes lot of time..to upload as well as to to download chat history..
If you are using such tools or any other which help me out on this issue..
Thank you..!!
No, I'm not using any tool, I just lower the device photo quality to 1 MP.
I searched but didn't find anything to compress the image or the base64 string. If you know @pap5508 or @NickIliev know any please let me know.
@emmanuel128 : how you define photo quality to 1MP in iOS..?
@pap5508 I do it on android on the phone camera settings, not in the code.
The issue still reproduces with {N} 3.0.0 RC.
This also appears to happen when you call saveToFile on android as well. The following code crashes at var saved...
var folder = android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_PICTURES);
if (!folder.isDirectory()) {
try {
folder.mkdir();
} catch (e) {
e.printStackTrace();
}
}
var fileName = 'img_' + new Date().getTime() + '.jpg';
var path = folder + '/' + fileName;
var imageSource = imageSourceModule.fromNativeSource(webImage.android);
var saved = imageSource.saveToFile(path, enums.ImageFormat.jpeg);
Hey, @davecoffin keep in mind that for Android API23 and above you will need explicit permissions (given runtime) to have access to the external storage and to be able to save images. While for lower API versions you can add those permissions in the AndroidManifest.xml file for API23 and above you will need them once in your AndroidManifest.xml and then you should ask for them when needed.
Here you can find an example application recreating your scenario and using nativescript-permissions to grant the permissions on Page loaded event.
Thanks! My problem ended up being that I wasnt passing an acceptable image object. I was trying to derive the native source from a Web Image object from this plugin: https://www.npmjs.com/package/nativescript-web-image-cache but couldnt figure it out. So I got the image source from the URL. More on that here: https://discourse.nativescript.org/t/how-to-save-an-imagesource-object-to-the-devices-photo-library-on-both-ios-and-android/1126
I found another alternative!
cameraModule.takePicture({\
width: 1280, height: 720, keepAspectRatio: false, saveToGallery: false
}).then(function (imageAsset) {
imageAsset.getImageAsync(function (res){
console.log(res);
viewModel.set("BoardingPassSource", imageSource);
var image = ImageSourceModule.fromNativeSource(imageSource);
viewModel.set("base64String", image.toBase64String('png'));
// var stream;
// var comp = image.android.compress("png", 70, stream);
console.log("image selected");
});
}).catch(function (err) {
console.log("Error -> " + err.message);
});
now I want to find a way to compress the ImageAsset or the ImageSource.
Any suggestions? @pap5508 @NickIliev
@emmanuel128 so do i锛宒id you find the solution?
I am having the same issue.
Thanks to @emmanuel128 reached as far as he reached, and I am using the latest modules as mentioned below:
nativescript -- 3.0.1
tns-core-modules -- 3.0.1
tns-android -- 3.0.0
Getting error: TypeError: this.android.compress is not a function
/tns-core-modules/image-source/image-source.js line: 141, column:21.
i have solved my problem
startSelection(context, pageObj, imageItems, cb) {
var _this = this;
imageItems = imageItems ? imageItems : this.imageItems;
context
.authorize()
.then(function () {
// imageItems.length = 0;
return context.present();
})
.then(function (selection) {
selection.forEach(function (selected_item) {
selected_item.getImage().then(function (imagesource) {
//bad code
/* var folderPath = android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).toString();
// let folder = fs.knownFolders.documents();
var fileName = "jzt_" + new Date().getTime() + ".jpeg";
let path = fs.path.join(folderPath, fileName);
//鏌ョ湅婧愮爜淇敼
//https://github.com/NativeScript/NativeScript/blob/master/tns-core-modules/image-source/image-source.android.ts
let saved = imagesource.saveToFile(path, enums.ImageFormat.jpeg, 5);
if (saved) {
var task = _this.sendImages(path, cb);
var item = new observable.Observable();
item.set("thumb", imagesource);
item.set("uri", fileName);
item.set("uploadTask", task);
item.set("url", imagesource);
if (pageObj) {
pageObj.bindingContext.set('srcThumb', imagesource);
}
imageItems.push(item);
}
_this.counter++;*/
//good code
var localPath=null;
if (platformModule.device.os === "Android") {
localPath = selected_item.android;
} else {
localPath = selected_item.ios;
}
if (localPath) {
var task = _this.sendImages(localPath, cb);
var item = new observable.Observable();
item.set("thumb", imagesource);
item.set("uri", localPath);
item.set("uploadTask", task);
item.set("url", imagesource);
if (pageObj) {
pageObj.bindingContext.set('srcThumb', imagesource);
}
imageItems.push(item);
}
})
});
}).catch(function (e) {
console.log(e.eventName);
});
see:https://gist.github.com/giscafer/30ac4883f12dd3809d00926618925305
pull request:https://github.com/NativeScript/sample-ImageUpload/pull/14
+1 from t.1125152
@emmanuel128
Where is viewModel defined?
var image = ImageSourceModule.fromNativeSource(imageAsset);
you need to assign nativeImage to this method.
change it to:
var image = ImageSourceModule.fromNativeSource(imageAsset.nativeImage);
Hello @emmanuel128, @pap5508 and All,
The API could be misleading here and as @emmanuel128 suggested, the proper way to implement this is as follow:
cameraModule.takePicture({
width: 1280, height: 720, keepAspectRatio: false, saveToGallery: false
}).then(function (imageAsset) {
console.log("Result is an image asset instance");
viewModel.set("BoardingPassSource", imageAsset);
imageAsset.getImageAsync(image => {
let imageSource = ImageSourceModule.fromNativeSource(image);
let encodedString = imageSource.toBase64String("jpeg");
console.log(encodedString);
})
}).catch(function (err) {
console.log("Error -> " + err.message);
});
I opened https://github.com/NativeScript/NativeScript/pull/5273 in order to throw if the source is not a correct native instance.
A sample application could be found here.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
I found another alternative!
now I want to find a way to compress the ImageAsset or the ImageSource.
Any suggestions? @pap5508 @NickIliev