This blog is to share my experience in implementing a very common requirement - attach a photo by integrating with device camera or photo library and then passing the photo as Base64-encoded string.
a. Create a Java class say PhotoUtility.
b. MAF provides method getPicture to integrate with camera and photo library
@Params
quality – Quality of saved image. Range is [0, 100]. Higher the quality higher will be the image size. So, 30-50 is good value for quality. For iOS set quality below 50 to avoid memory error on some devices. It might give memory errors when quality is more than 50.
destinationType – Choose the format of the return value.
DeviceManager.DESTINATIONTYPE_FILE_URI (1) => The file is saved in application`s temporary directory and it Returns image as a filename URI.
DeviceManager.CAMERA_DESTINATIONTYPE_DATA_URL (0) => Returns image as Base64-encoded String which can be passed in a webservice.
sourceType – Source of the image
DeviceManager.SOURCETYPE_PHOTOLIBRARY (0) => photo library
DeviceManager.SOURCETYPE_CAMERA (1) => Camera
allowEdit – Allow simple editing of image before selection. It is ignored in android device.
encodingType – Choose the encoding of the returned image file.
DeviceManager.ENCODING_TYPE_PNG (1) => PNG image is returned
DeviceManager.CAMERA_ENCODINGTYPE_JPEG (0) => jped image is returned
targetWidth – Width in pixels to scale image. Aspect ratio is maintained. A negative or zero value indicates that the original dimensions of the
image will be used.
targetHeight – Height in pixels to scale image. Aspect ratio is maintained. A negative or zero value indicates that the original dimensions of the
image will be used.
@Return
a String representing either base64-encoded image data or a file URI, depending on the value of destinationType.
Add the below code in java class which in turn uses getPicture method
private String photo = "";
public void setPhoto(String photo) {
String oldPhoto = this.photo;
this.photo = photo;
propertyChangeSupport.firePropertyChange("photo", oldPhoto, photo);
}
public void getPhotoFromCamera() {
String photo1 =
DeviceManagerFactory.getDeviceManager().getPicture(40, DeviceManager.CAMERA_DESTINATIONTYPE_DATA_URL,
DeviceManager.CAMERA_SOURCETYPE_CAMERA, false,
DeviceManager.CAMERA_ENCODINGTYPE_JPEG, 1000, 1000);
photo1 = "data:image/gif;base64," + photo1;
setPhoto(photo1);
}
-------------------------------------------------------------------------------------------------------------------------
public void getPhotoFromLibrary() {
String photo1 =
DeviceManagerFactory.getDeviceManager().getPicture(40, DeviceManager.CAMERA_DESTINATIONTYPE_DATA_URL,
DeviceManager.CAMERA_SOURCETYPE_PHOTOLIBRARY, false,
DeviceManager.CAMERA_ENCODINGTYPE_JPEG, 1000, 1000);
photo1 = "data:image/jpeg;base64," + photo1;
setPhoto(photo1);
}
In the above code data:image/jpeg;base64, is the data URL scheme header. This is required to show an image using base64-encoded string.
Right click your java class and create Java and Create Data Control.
<amx:image inlineStyle="width:60%;max-width:100%;margin-top:10px" id="i1"
source="#{bindings.photo.inputValue}"/>
You can change the inlineStyle based on your need.
Now one by one drag and drop getPhotoFromCamera() and getPhotoFromLibrary() methods from Data Control palette to create a MAF button or link.
It will look like this:
<amx:commandButton actionListener="#{bindings.getPhotoFromCamera.execute}" text="Take New Photo"
id="cb3"
/>
<amx:commandButton actionListener="#{bindings.getPhotoFromLibrary.execute}" text="Chose Existing Photo"
id="cb4"
/>
You can use a panel group layout vertical to give a better look and feel:
<amx:panelGroupLayout id="pgl1" layout="vertical" halign="center">
<amx:image inlineStyle="width:60%;max-width:100%;margin-top:10px" id="i1"
source="#{bindings.photo.inputValue}"/>
<amx:spacer id="s1" height="20" width="20"/>
<amx:commandButton actionListener="#{bindings.getPhotoFromCamera.execute}" text="Take New Photo"
id="cb3"
/>
<amx:commandButton actionListener="#{bindings.getPhotoFromLibrary.execute}" text="Chose Existing Photo"
id="cb4"
/>
</amx:panelGroupLayout>
Here is how your page will look like
(Note : I have applied some style class to buttons)
I hope it is helpful.
Following the above principle and with some java coding we can even build a page where user can add multiple attachments.
Something like below:
Cheers,
Deepak
STEP 1: Enable camera plugin in your maf-application.xml
STEP 2: Using getPicture method to integreate with device camera and photo library
a. Create a Java class say PhotoUtility.
b. MAF provides method getPicture to integrate with camera and photo library
getPicture method
@Params
quality – Quality of saved image. Range is [0, 100]. Higher the quality higher will be the image size. So, 30-50 is good value for quality. For iOS set quality below 50 to avoid memory error on some devices. It might give memory errors when quality is more than 50.
destinationType – Choose the format of the return value.
DeviceManager.DESTINATIONTYPE_FILE_URI (1) => The file is saved in application`s temporary directory and it Returns image as a filename URI.
DeviceManager.CAMERA_DESTINATIONTYPE_DATA_URL (0) => Returns image as Base64-encoded String which can be passed in a webservice.
sourceType – Source of the image
DeviceManager.SOURCETYPE_PHOTOLIBRARY (0) => photo library
DeviceManager.SOURCETYPE_CAMERA (1) => Camera
allowEdit – Allow simple editing of image before selection. It is ignored in android device.
encodingType – Choose the encoding of the returned image file.
DeviceManager.ENCODING_TYPE_PNG (1) => PNG image is returned
DeviceManager.CAMERA_ENCODINGTYPE_JPEG (0) => jped image is returned
targetWidth – Width in pixels to scale image. Aspect ratio is maintained. A negative or zero value indicates that the original dimensions of the
image will be used.
targetHeight – Height in pixels to scale image. Aspect ratio is maintained. A negative or zero value indicates that the original dimensions of the
image will be used.
@Return
a String representing either base64-encoded image data or a file URI, depending on the value of destinationType.
Add the below code in java class which in turn uses getPicture method
private String photo = "";
public void setPhoto(String photo) {
String oldPhoto = this.photo;
this.photo = photo;
propertyChangeSupport.firePropertyChange("photo", oldPhoto, photo);
}
public void getPhotoFromCamera() {
String photo1 =
DeviceManagerFactory.getDeviceManager().getPicture(40, DeviceManager.CAMERA_DESTINATIONTYPE_DATA_URL,
DeviceManager.CAMERA_SOURCETYPE_CAMERA, false,
DeviceManager.CAMERA_ENCODINGTYPE_JPEG, 1000, 1000);
photo1 = "data:image/gif;base64," + photo1;
setPhoto(photo1);
}
-------------------------------------------------------------------------------------------------------------------------
public void getPhotoFromLibrary() {
String photo1 =
DeviceManagerFactory.getDeviceManager().getPicture(40, DeviceManager.CAMERA_DESTINATIONTYPE_DATA_URL,
DeviceManager.CAMERA_SOURCETYPE_PHOTOLIBRARY, false,
DeviceManager.CAMERA_ENCODINGTYPE_JPEG, 1000, 1000);
photo1 = "data:image/jpeg;base64," + photo1;
setPhoto(photo1);
}
In the above code data:image/jpeg;base64, is the data URL scheme header. This is required to show an image using base64-encoded string.
Right click your java class and create Java and Create Data Control.
STEP 3: Using DC methods in AMX page
Drag drop photo attribute from Data Control paletter to create a MAF input text. This is just to create the bindings. Now delete the input text from the source. Don`t delete it from Data Struture. Just delete it from the editor. And add the below code for image:<amx:image inlineStyle="width:60%;max-width:100%;margin-top:10px" id="i1"
source="#{bindings.photo.inputValue}"/>
You can change the inlineStyle based on your need.
Now one by one drag and drop getPhotoFromCamera() and getPhotoFromLibrary() methods from Data Control palette to create a MAF button or link.
It will look like this:
<amx:commandButton actionListener="#{bindings.getPhotoFromCamera.execute}" text="Take New Photo"
id="cb3"
/>
<amx:commandButton actionListener="#{bindings.getPhotoFromLibrary.execute}" text="Chose Existing Photo"
id="cb4"
/>
You can use a panel group layout vertical to give a better look and feel:
<amx:panelGroupLayout id="pgl1" layout="vertical" halign="center">
<amx:image inlineStyle="width:60%;max-width:100%;margin-top:10px" id="i1"
source="#{bindings.photo.inputValue}"/>
<amx:spacer id="s1" height="20" width="20"/>
<amx:commandButton actionListener="#{bindings.getPhotoFromCamera.execute}" text="Take New Photo"
id="cb3"
/>
<amx:commandButton actionListener="#{bindings.getPhotoFromLibrary.execute}" text="Chose Existing Photo"
id="cb4"
/>
</amx:panelGroupLayout>
Here is how your page will look like
(Note : I have applied some style class to buttons)
STEP 4 : Passing Base64-encoded String to REST service
Now photo attribute contains the image along with Data URI scheme header(data:image/jpeg;base64,). When sending through REST service we need to remove it and call REST service using REST Service Adapter.I hope it is helpful.
Following the above principle and with some java coding we can even build a page where user can add multiple attachments.
Something like below:
Cheers,
Deepak
Great .. but How Can I Capturing Image from ADF Web Based Application ?
ReplyDeleteThanks for this tutorial, but
ReplyDeleteHow can i save this image on my mobile device
Plzzzzzzzzz Help
Hi Ujjwal,
DeleteSorry for late reply.
Either you can save Base64-encoded string or you can save the image with in the application as well.
I hope you would have completed this requirement till now.
Regards,
Deepak
Hi deepak,
Deletenow i can see the image in my gallery, but when i click the pic on the same time when i check gallery i am not able to find the image in my phone after 5 to 30 min i ca see that image. why this so please help me
i would like to save this image in my database using Rest. what should be the type of image in my database (either Blob or String). Since the type of photo is String
DeleteHello Sir,
ReplyDeleteI have created a table in oracle database which support utf-8(Hindi) format. Now i want to retrieve these utf-8 value in my Oracle MAF application
As i am new to Oracle MAF i don't have any idea how to achieve this
please help me.....
Thanks & Regard
Ujjawal Srivastava
how to upload multiple images at a time
ReplyDeleteI'm hitting following exception -
ReplyDelete07-07 19:49:26.358: D/CordovaInterfaceImpl(14708): Sending activity result to plugin
07-07 19:49:26.382: D/CameraLauncher(14708): File locaton is: /storage/emulated/0/Download/Pizigani_1367_Chart_10MB.jpg
07-07 19:49:27.105: I/ExifInterface_JNI(14708): Raw image not detected
07-07 19:49:27.112: I/ExifInterface_JNI(14708): Raw image not detected
07-07 19:49:27.138: D/JVM(14708): AttachmentBean: getPhotoFromGallery: Caught IOException: java.nio.file.NoSuchFileException: /storage/emulated/0/Android/data/com.oraclecorp.vertical.cg.RetailExecution/cache/Pizigani_1367_Chart_10MB.jpg?1499482167122
Do you know how i can resolve this ? This i'm trying to open a image from photo album