What is Camera Plus?
Camera Plus is a NativeScript plugin recently open sourced from the team at nStudio. Prior to being open sourced the plugin was developed privately with the support of LiveShopper. This plugin allows you to embed a UI component into your layouts. So you can create applications with custom camera layouts. The plugin provides a lot of functionality out of the box. For this guide we’ll stick to the core functionality of installing and using the plugin to take a picture.
Installation
We will assume you already have the NativeScript CLI installed or are at least familiar with how to add plugins to your project. If not, the Getting Started guide will provide everything you need to set up your development machine.
Open your terminal and run the following command to install the plugin into your project.
tns plugin add @nstudio/nativescript-camera-plus
Example Screen
You might be asking yourself why is the camera oriented differently than the device. Short answer, the gif was recorded from an Android emulator using a webcam from a MBP. Long answer, no one really knows but it’s because the webcam is mirrored and rotated and that’s just how cameras work. No one really knows so Google and try to find out how everyone “thinks” they work until you give up searching.
Usage
Now that we have the plugin installed we can drop the CameraPlus view component into our UI layout and use it. We are going to look at a plain NativeScript app using the XML markup for the page layout. The plugin also works in Angular applications and should have no issues working with any framework integration (Vue or others in the future) into NativeScript since the plugin relies on the core and has no dependencies on any framework.
<Page xmlns:Cam="@nstudio/nativescript-camera-plus"> <Page.actionBar> <ActionBar title="Camera Plus Demo" icon=""></ActionBar> </Page.actionBar> <StackLayout> <Cam:CameraPlus id="camPlus" saveToGallery="true" showCaptureIcon="true" showGalleryIcon="true" showToggleIcon="true" showFlashIcon="true" debug="true"> </Cam:CameraPlus> </StackLayout> </Page>
What we have here is a simple page, all we are doing is declaring the `xmlns` (xml namespace) on the `Page` which points to the plugin in your project. Then dropping the CameraPlus view into our page. This will work with any layout, you can overlay buttons on the camera, images, any other view or layout.
Taking a Picture
Remember how I said this plugin provides a lot of functionality, well just looking at our markup you can see we have 6 custom props on the CameraPlus that are not typical for NS view components, these are specifically for the CameraPlus and there are more, over 10 more props that can be declared. The props being used in this sample are basic and allow us to show some built in icons by setting them to `true`. If we set `showCaptureIcon` to false then the capture (take picture) icon built into the CameraPlus will not be rendered and we’ll have to create our own way of letting the user take a picture. In this example, we’re not going to create our own UI but instead use what is built in. The CameraPlus exposes several events you can listen for in your application, the one for getting an image when a picture is taken is `photoCapturedEvent`. This event is emitted from the CameraPlus instance and will return an `ImageAsset` in the event.
Show The Damn Code Already
Okay Okay, here it is:
import { topmost } from 'tns-core-modules/ui/frame'; import { fromAsset } from 'tns-core-modules/image-source'; import { CameraPlus } from '@nstudio/nativescript-camera-plus'; const cam = topmost().currentPage.getViewById("camPlus") as CameraPlus; cam.on(CameraPlus.photoCapturedEvent, args => { fromAsset(args.data).then(result => { // result is an ImageSource that we got by using fromAsset in the image-source module. }); });
Now let’s do a break down of the code.
First, we are importing `topmost` from the core frame module and the `fromAsset` method from the image-source module, and last we import the `CameraPlus` class from the plugin.
Next, we’re getting the instance of our CameraPlus from our page by its `id`.
Last, we use the `on` method to setup our event listener for the `photoCapturedEvent` that the CameraPlus will emit when a picture is taken. This event returns an object and the `data` prop will contain the `ImageAsset` which is the image taken from the camera.
Wrapping Up
By now you should have a quick introduction to the newly open sourced CameraPlus plugin and how to integrate it into your NativeScript applications. We added the CameraPlus to our UI layout, grabbed an instance of the component from our code and listened to the `photoCapturedEvent` to be emitted when pictures are taken.
A huge thanks is due to Austin Larue and Shawn Pavel of LiveShopper for sponsoring the plugin development.
This is awesome! Very happy to see that this is now open source ❤ Thanks LiveShopper and nStudio!
LikeLike
Thanks Brad, LiveShopper, and nStudio. This is amazing!!
How would one use the takePicture() function and get the picture data? I have tried a few things but to no avail.
In the xml I want to set: showCaptureIcon=”false” and then in the js take a photo and capture the data.
As a basic example, thinking something along the lines of:
import { CameraPlus } from ‘@nstudio/nativescript-camera-plus’;
function onNavigatingTo(args) {
var page = args.object;
CameraPlus.takePicture(data){
// use the data in base64 or bytes.
};
}
LikeLike
Hi MikeP, this is where you can use the events that are emitted: https://github.com/nstudio/nativescript-camera-plus/blob/master/demo/app/main-view-model.ts#L38 – right now I don’t think the `takePicture` method returns a promise or anything. Definitely something that can be added to provide different coding styles. Hope this helps. If not, ping the repo and we can help look at any issue.
LikeLike
Hi….
when i use plugin and deploy on android-Kitkat it works fine, but same code when i deploy on lolipop version the captured image is blurred
fromAsset((args).data).then(res => {
const testImg = topmost().getViewById(“testImagePickResult”) as Image;
testImg.src = res;
alert(+res.width); //width is coming 120 when i set the “params.setPreviewSize(640, 480);”
});
the
LikeLike
Hi
I have two images inside a Stacklayout, is possible to save the composition like image in the dispositif? like a photo frame APP
Thanks
LikeLike
Hello brad ;
Very good job;
How can i use the same code in javascript ?
Thanks
LikeLike
just download github repo. and run , while running it generates javascript files. then delete all ts files thats it.
LikeLike
hello brad …! i tried to implement some custom layout but failed. i think this plugin wont support custom layout. can you confirm it…..
LikeLike
hello brad…! really custom view is not at all working. so in order to show the problem i have made a playground sample where i removed flash icon by making its prop to false. and added custom button in that place.
https://play.nativescript.org/?template=play-js&id=zNigfq
kindly have a look at it….
LikeLike
Hi, can I use this plugin with the nativescript-мгу? If so, how?
LikeLike
Hey 🙂 Unfortunately the xml-tag is not working. Do you have any idea why?
LikeLike
It’s grate …but in my case it not showing Capture Icon i have checked every thing showCaptureIcon=”true” also please help
LikeLike
And mage get save in galary while I have set saveToGallery=”false”
LikeLike
“No one really knows so Google and try to find out how everyone “thinks” they work until you give up searching.”
Best quote of the year mate 😀 !!
Awesome article, thanks and cheers from across the pond.
LikeLike