Join Rafael Hernandez for an in-depth discussion in this video Taking photos and video with the hardware camera, part of Up and Running with Titanium.
One of the strongest features of a Titanium is the ease at which you can use the device hardware camera. I have started an application that has two elements. A yellow area, and a button called captured media. When we tap the button, capture media, the hardware camera will launch, will take a picture, and then the picture will be placed within the yellow area. In our code, I've created the media button at lines 26 through 29, and the yellow area in lines 31 through 36. As well, there's an event listener for the button at lines 41 through 43, and that's where we will start.
To call the camera, we'll type TI.Media.showCamera. And, within the creation arguments, we'll need to define a function for success. And that's when we actually take a picture and succeed. For now, I'll leave it blank when we cancel, and then, when there's an error. Now, I could actually define these functions in place by typing function, and then going through the process of writing a function.
Instead, I'll create an overall object that will handle these three conditions. That object will be called camera. And then I'll define methods called onSuccess, and then camera.onCancel and, finally, camera.onError. Now, above the event listener, I'll create the camera object var camera =, and then I'll open an empty object. This object will have three properties; onSuccess, and that will be a function which will take the event object.
It will have onCancel. That's also a function that takes the event object. And onError. Which takes event object. Now, in case your wondering, how do we know that it takes the event object. Well, that's because the event object from addEventListener is passed into whatever function we define for these properties. So then it basically passes into the argument for these functions.
We'll start backwards. We'll define the error and cancel functions first, and then the success. So, if there's an error, we will place an alert dialog on the screen. And that alert dialog will say, this is not a photo or a video. We can, as well, just say this is an error. But this will be evident in a moment. Within cancel, alert, photo cancelled. Now within success, we'll break it down into multiple parts. The camera is capable of taking photos and video.
Here, I'm going to show you how to take a photo. To take a video, I'll show you where you can change a setting, and it's really easy to get going. So we'll want to test to see if, indeed, we've taken the photo, so if e.mediaType is TI.Media.MEDIA_TYPE_PHOTO. So if you were taking a video, you would use video instead.
So, basically, if we have taken a photo then we'll have the photo code there. Now, we'll be a little bit flexible. Else if e.mediaType is a video, TI.media.MEDIA_TYPE_VIDEO, Then we'll have another conditional branch. Now if its neither a photo or video, then lets tell ourselves that. Else, alert, This is not a photo or video.
And you ask yourself, now why would we do that? Well, remember, we could take this code and we could this modular and if we drop this into another file, and ahead of time, we've taken care of error control. So, now, within the branch that handles the photos, we'll write code that will take the photo taken by the camera and then place it within the yellow area. What this means is that eventually we will need an image view if we take a photo. And, if we were to implement the video, we would need a video view. We'll write that code, but we won't shoot video. So, outside of this object, we're going to create two forward references, var img, which will be our image view eventually, and var vid, which would be a video view.
We're not going to use it, but should you happen to implement the video as you try this out it will use that instead. If you ask yourself, why are we placing them outside of the function? It's so that we can use them in either three functions or we can use them in other functions in our code. It prepares them for use. Now, within the photo branch, we'll create code to detect whether we have taken a photo already. If we have, the value of img won't be false, it'll be true. So if we've taken a photo, then if img, then what we're going to need to do is wipe out that photo and replace it with a new one.
So, the photo is being placed in media view, so mediaView.remove img. So we're removing the image view from the media view. Now, there's no else clause, it's just checking if we've already taken the photo. Now, that the photo would be removed, or if it doesn't exist, img = TI.UI.createImageView. So we've prepared an image view, and we'll set the image property equal to the result of e.media.
And this is where the file is actually contained after we take the photo. Now the file is of a type called blob. And it's not a photo, as we know it, until it's actually stored within your device gallery. But we'll look at some other features that you can use with the blob object, such as resizing the photo. Blob objects have lots of different methods that you can use to work with them, specifically there's some resize methods, some cropping methods. I won't show them here but I will show you, eventually, in the documentation where you can look them up. Next we will specify the z-index property.
Normally we don't do this but here we're going to do it in case we wanted to overlay anything on the image view by adding it to media view. So the lower the number, the lower it is in the stack. So we'll set right at 0, so it's at the bottom of the stack. Now we need to add the image view to media view, mediaView.add img. Now in case you shot the video, you would do the same thing as you did with the photo, so if vid, then you would remove it, mediaView.remove(vid).
Then you would add a video player, so vid = TI.Media.createVideoPlayer. And you would set the media property to e.media. Just as we added the image view to the media view, we will add the video player to the media view, mediaView.add(vid). Okay, before we test this out, we'll go back to the function show camera.
There are a few other parameters that we can include. One of them is a parameter called allow editing, and it's a parameter that is only good for iOS. And what this will do, is it will add a square on top of the picture we've taken that will act as a bounds area, so that we scale and resize the pic and we will get that image in return. On Android this will not appear. As well, we can specify if we just want to take photos, videos, or take both. That's done with media types. And we set that to an array. And we use the special constant TI.Media.MEDIA_TYPE_PHOTO.
And there's a special constant for videos, you would just type a comma, and then add it as the second entry. We won't do that here. Now this next property is a bit deceiving. It's called video quality, but it actually does apply to photo quality as well. We'll set that to the constant TI.Media.QUALITY_HIGH. Finally, if we want to save this to the device photo gallery, saveToPhotoGallery.
And set that to true. So when we take the photo, it will automatically be saved to the photo gallery, regardless of what we do in our application. So now let's test this. We'll try to test it in the simulator first, and then we'll see what happens. So now, in the simulator, if I tap the capture media button I get this is not a photo or a video. There's actually not a way to test out the camera within the simulator. You would think maybe it would use the web cam. It doesn't. Instead we do have to build this to device. So I'll quit the simulator and then I'll deploy this to device.
Now I cover, more in detail, the deployment of an app to device later in the course. Here I'll just run through it quickly. I'll head over to an application called Reflector, which has the content of my device on Airplay. And now, I will choose our application. And I'll take a picture by tapping Capture Media. And here, get it just right, Now, you'll see a square around the image that I've taken. That's the property called allow editing, and it's set to true. If it wasn't set to true, we would just be taken straight back to the application.
So I could pan. I'm dragging it around, or I could use a two finger zoom. Let me get. There we go. Beautiful. And now, I'll choose use photo. And the first time you do this, you should know that user will be asked if your app should have permission to use photos. So choose okay. If they choose not to, well then they have chose not to basically go through the permissions of allowing your app. If they do it again, they will prompted again to allow permissions. But now we see, in the yellow area, a picture of our honey bear, and if we take another photo, capture media, take a distance shot.
Use photo. Then it detects that we had a photo, removes it from the view, and then puts the new photo in the view. Though the media API can be used to capture both photos and videos on iOS, on Android it can only be used to capture photos. Capturing videos on Android is unfortunately a complicated process, and we won't cover it here as the Titanium API does not directly support it. A few of the developers in the Titanium developer community have ventured to find a solution but, as of now, there isn't, officially supported, an API that addresses this gap.
It's important to note, however, that this limitation does not affect Android's ability to play back video with Titanium. And more importantly, capture media for use in mobile applications.
- Setting up Titanium Studio
- Creating a new project
- Adding interactivity
- Using CommonJS modules
- Including platform-specific code
- Creating a preferences panel
- Making cross-platform adjustments