Crop and save the image - xamarin.android

I used the following method as I wanted:
1-I want to open the camera, select image, crop and save the image in imageview
2- Crop and save a saved image inside the device in imageview
erro
open camera
open gallery
full project
https://drive.google.com/file/d/1tUSTyiq5qUPpaY6z2Jd1m2tv_HRE-QuL/view?usp=sharingusp=sharing
public class MainActivity : AppCompatActivity
{
ImageView imageView;
Android.Support.V7.Widget.Toolbar toolbar;
File file;
Android.Net.Uri uri;
Intent CamIntent, GalIntent, CropIntent;
const int RequestPermissionCode = 1;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
toolbar.Title = "Crop Image";
toolbar.SetTitleTextColor(Android.Graphics.Color.White);
SetSupportActionBar(toolbar);
imageView = FindViewById<ImageView>(Resource.Id.imageView);
int permissionCheck = (int)ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera);
if (permissionCheck == (int)Permission.Denied)
RequestRuntimePermission();
}
private void RequestRuntimePermission()
{
if (ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.Camera))
Toast.MakeText(this, "CAMERA permission will allows us to access CAMERA app", ToastLength.Short).Show();
else
ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.Camera }, RequestPermissionCode);
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.menu_main, menu);
return true;
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
if (item.ItemId == Resource.Id.btn_camera)
CameraOpen();
else if (item.ItemId == Resource.Id.btn_gallery)
GalleryOpen();
return true;
}
private void GalleryOpen()
{
GalIntent = new Intent(Intent.ActionPick, MediaStore.Images.Media.ExternalContentUri);
StartActivityForResult(Intent.CreateChooser(GalIntent, "Select image from Gallery"), 2);
}
private void CameraOpen()
{
CamIntent = new Intent(MediaStore.ActionImageCapture);
file = new File(Android.OS.Environment.ExternalStorageDirectory, "file_image" + DateTime.Now + ".jpg");
uri = Android.Net.Uri.FromFile(file);
CamIntent.PutExtra(MediaStore.ExtraOutput, uri);
CamIntent.PutExtra("return-data", true);
StartActivityForResult(CamIntent, 0);
}
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
if (requestCode == 0 && resultCode == Result.Ok)
CropImage();
else if (requestCode == 2)
{
if (data != null)
{
uri = data.Data;
CropImage();
}
}
else if (requestCode == 1)
{
if (data != null)
{
Bundle bundle = data.Extras;
Bitmap bitmap = (Bitmap)bundle.GetParcelable("data");
imageView.SetImageBitmap(bitmap);
}
}
}
private void CropImage()
{
try
{
CropIntent = new Intent("com.android.camera.action.CROP");
CropIntent.SetDataAndType(uri, "image/*");
CropIntent.PutExtra("crop", "true");
CropIntent.PutExtra("outputX", 180);
CropIntent.PutExtra("outputY", 180);
CropIntent.PutExtra("aspectX", 3);
CropIntent.PutExtra("aspectY", 4);
CropIntent.PutExtra("scaleUpIfNeeded", true);
CropIntent.PutExtra("return-data", true);
StartActivityForResult(CropIntent, 1);
}
catch
{
}
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
{
switch (requestCode)
{
case RequestPermissionCode:
{
if (grantResults.Length > 0 && grantResults[0] == Permission.Granted)
Toast.MakeText(this, "Permission Granted", ToastLength.Short).Show();
else
Toast.MakeText(this, "Permission Canceled", ToastLength.Short).Show();
}
break;
}
}
}

1-I want to open the camera, select image, crop and save the image in imageview
2- Crop and save a saved image inside the device in imageview
If you want to do this, I suggest you can use XamarinAndroidImageCropper to do.
Firstly, install XamarinAndroidImageCropper by Manage Nuget package...., then add permissions to manifest.
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Using CropImageView like this:
<com.theartofdev.edmodo.cropper.CropImageView
android:id="#+id/cropImageView"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cropAspectRatioX="16"
app:cropAspectRatioY="9"
app:cropBackgroundColor="#88AA66CC"
app:cropBorderCornerColor="#android:color/holo_blue_bright"
app:cropBorderCornerOffset="0dp"
app:cropBorderCornerThickness="5dp"
app:cropBorderLineColor="#android:color/holo_green_light"
app:cropBorderLineThickness="1dp"
app:cropGuidelines="on"
app:cropGuidelinesColor="#android:color/holo_red_dark"
app:cropInitialCropWindowPaddingRatio="0"
app:cropSnapRadius="0dp"/>
More detailed info, please take a look:
https://github.com/mikescandy/Xamarin-Cropper

Related

Resize and Screen.Orientation event from WKWebView Xamarin not working in Angular

I have a Xamarin mobile app who include a WebView.
This one display an Angular Website.
When I change my mobile orientation, our Angular code doesn't catch this event on iOS (WKWebView).
But I don't have any troubles with the Android WebView, Resize and screen orientation events are catched.
Then I supposed my problem is on the iOS Xamarin part.
Angular window resize event catch :
#HostListener('window:resize', ['$event'])
resizeMap() {
this.mapWidth = window.innerWidth;
this.mapHeight = window.innerHeight;
this.changeDetectorRef.detectChanges();
this.mapService.map.updateSize();
}
Angular screen orientation event catch
screen.orientation.addEventListener('change', () => {
const { type } = screen.orientation;
if (!type.startsWith('portrait')) {
Swal.fire(
this.l('Information'),
this.l('LandscapeOrientationNotRecommended'),
'info'
);
// alert(this.l('LandscapeOrientationNotRecommended'));
}
});
Custom Xamarin iOS WKWebView
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == "Source")
{
if (Element.Source != null)
{
Control.LoadRequest(new NSUrlRequest(new NSUrl(Element.Source)));
}
}
}
protected override void OnElementChanged(ElementChangedEventArgs<CustomWebView> e)
{
base.OnElementChanged(e);
this.AutoresizingMask = UIViewAutoresizing.FlexibleDimensions;
this.ContentMode = UIViewContentMode.ScaleToFill;
if (e.OldElement != null)
{
userController.RemoveAllUserScripts();
userController.RemoveScriptMessageHandler("invokeAction");
var hybridWebView = e.OldElement as CustomWebView;
hybridWebView.Cleanup();
}
if (e.NewElement != null)
{
if (Control == null)
{
userController = new WKUserContentController();
var script = new WKUserScript(new NSString(JavaScriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
userController.AddUserScript(script);
userController.AddScriptMessageHandler(this, "invokeAction");
var config = new WKWebViewConfiguration { UserContentController = userController };
var webView = new WKWebView(Frame, config);
SetNativeControl(webView);
}
if (Element.Source != null)
{
string contentDirectoryPath = Path.Combine(NSBundle.MainBundle.BundlePath);
Control.LoadHtmlString(Element.Source, new NSUrl(contentDirectoryPath, true));
}
}
}
public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
{
if (message.Body != null)
{
Element.InvokeAction(message.Body.ToString());
}
}
}
}
If someone have any suggestions ?
Thanks for your help.

How to remove item from array in image adapter. Xamarin gallery

public class ImageAdapter : BaseAdapter
{
Context context;
public ImageAdapter (Context conn)
{
context = conn;
}
public override int Count { get { return thumbIds.Length; } }
public override Java.Lang.Object GetItem (int position)
{
return null;
}
public override long GetItemId (int position)
{
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public override View GetView (int position, View convertView, ViewGroup parent)
{
ImageView pic = new ImageView (context);
pic.SetImageResource (thumbIds[position]);
pic.LayoutParameters = new Gallery.LayoutParams (500, 500);
pic.SetScaleType (ImageView.ScaleType.FitXy);
return pic;
}
// references to our images
int[] thumbIds = {
Resource.Drawable.image_1,
Resource.Drawable.image_2,
Resource.Drawable.image_3,
Resource.Drawable.image_4,
Resource.Drawable.image_5,
Resource.Drawable.image_6,
Resource.Drawable.image_7
};
}
How to remove item from array
https://learn.microsoft.com/en-us/xamarin/android/user-interface/controls/gallery
Gallery
Do you want to achieve the result like following GIF?
I advice your to use List<int> to replace of int[], then you can add a method called removeItem in the ImageAdapter like following code.
public void removeItem(int numToRemove)
{
if (numToRemove < thumbIds.Count)
{
thumbIds.RemoveAt(numToRemove);
this.NotifyDataSetChanged();
}
}
Here is code about ImageAdapter.cs
using Android.Views;
using Android.Widget;
using Java.Lang;
using System.Collections.Generic;
using System.Linq;
namespace App25
{
internal class ImageAdapter : BaseAdapter
{
private MainActivity mainActivity;
public ImageAdapter(MainActivity mainActivity)
{
this.mainActivity = mainActivity;
}
public override int Count { get { return thumbIds.Count; } }
public override Java.Lang.Object GetItem(int position)
{
return thumbIds[position];
}
public override long GetItemId(int position)
{
return position;
}
// create a new ImageView for each item referenced by the Adapter
public override View GetView(int position, View convertView, ViewGroup parent)
{
ImageView pic = new ImageView(mainActivity);
pic.SetImageResource(thumbIds[position]);
pic.LayoutParameters = new Gallery.LayoutParams(500, 500);
pic.SetScaleType(ImageView.ScaleType.FitXy);
return pic;
}
public void removeItem(int numToRemove)
{
if (numToRemove < thumbIds.Count)
{
thumbIds.RemoveAt(numToRemove);
this.NotifyDataSetChanged();
}
}
// references to our images
List<int> thumbIds = new List<int> {
Resource.Drawable.faded_div,
Resource.Drawable.icon,
Resource.Drawable.faded_div1,
Resource.Drawable.icon1,
Resource.Drawable.faded_div,
Resource.Drawable.icon2,
Resource.Drawable.faded_div
};
}
}
Here is MainActivity.cs
[Activity(Label = "#string/app_name", Theme = "#style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
ImageAdapter imageAdapter;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
Gallery gallery = (Gallery)FindViewById<Gallery>(Resource.Id.gallery1);
Button button1 = FindViewById<Button>(Resource.Id.button1);
imageAdapter = new ImageAdapter(this);
gallery.Adapter = imageAdapter;
button1.Click += Button1_Click;
}
int removeItem = 0;
private void Button1_Click(object sender, System.EventArgs e)
{
imageAdapter.removeItem(removeItem);
}
}
Here is my activity_main.xml.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="remove"
android:id="#+id/button1"
/>
<Gallery
android:id="#+id/gallery1"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
=============Update==================
If you want to achieve the long click ,push alert, then delete the item, you can refer to achieve a longclick event for your gallery like following code.
gallery.ItemLongClick += Gallery_ItemLongClick;
private void Gallery_ItemLongClick(object sender, AdapterView.ItemLongClickEventArgs e)
{
// throw new System.NotImplementedException();
Android.App.AlertDialog.Builder dialog = new Android.App.AlertDialog.Builder(this);
Android.App.AlertDialog alert = dialog.Create();
alert.SetTitle("Title");
alert.SetMessage("Do you want to remove this select item");
alert.SetButton("OK", (c, ev) =>
{
// Ok button click task
imageAdapter.removeItem(e.Position);
});
alert.Show();
}
Here is my running GIF.

Xamarin Forms iOS CustomRenderer not repainting

I have a custom renderer to display HTML formatted text in a UITextView. If I hard-code the text into the constructor of the page that contains the control (so it gets set in the custom control's OnElementChanged event), it displays fine. If I await a api call to get the text and then set it (so it gets set in the custom control's OnElementPropertyChanged event) it does not repaint. If I change the orientation of the device, the text appears. What do I need to add to get it to display the text when it is set?
[assembly: ExportRenderer(typeof(HtmlLabel), typeof(HtmlLabelRenderer))]
namespace MyApp.iOS.Renderers
{
class HtmlLabelRenderer : ViewRenderer<HtmlLabel, UITextView>
{
private UITextView _htmlTextView = new UITextView();
protected override void OnElementChanged(ElementChangedEventArgs<HtmlLabel> e)
{
base.OnElementChanged(e);
if (Element?.Text == null) return;
SetHtmlText(Element.Text);
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (string.Equals(e.PropertyName, "Text", StringComparison.CurrentCultureIgnoreCase))
{
SetHtmlText(((HtmlLabel)sender).Text);
_htmlTextView.SetNeedsDisplay();
}
base.OnElementPropertyChanged(sender, e);
}
private void SetHtmlText(string text)
{
var attr = new NSAttributedStringDocumentAttributes {DocumentType = NSDocumentType.HTML};
var nsError = new NSError();
_htmlTextView.Editable = false;
_htmlTextView.AttributedText = new NSAttributedString(text, attr, ref nsError);
_htmlTextView.DataDetectorTypes = UIDataDetectorType.All;
SetNativeControl(_htmlTextView);
}
}
}
Update : I got further by changing the OnElementChanged to:
protected override void OnElementChanged(ElementChangedEventArgs<HtmlLabel> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || Element == null) return;
SetHtmlText(e.NewElement.Text ?? string.Empty);
SetNativeControl(_htmlTextView);
}
now if I have more than one HtmlLabel on the page all except the first one displays.
Try changing from:
_htmlTextView.SetNeedsDisplay();
to
SetNeedsDisplay();
or,
(Control ?? NativeView).SetNeedsDisplay();
Sharada Gururaj is right, changing to derive from Editor worked for iOS .. but breaks Android. Though this seems brute force, I used conditional compilation to get it working...
namespace MyApp.Renderers
{
#if __IOS__
public class HtmlLabel : Editor
{
}
#else
public class HtmlLabel : Label
{
}
#endif
}
Here is the android
[assembly: ExportRenderer(typeof(HtmlLabel), typeof(HtmlLabelRenderer))]
namespace MyApp.Droid.Renderers
{
public class HtmlLabelRenderer : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
var view = (HtmlLabel)Element;
if (view?.Text == null) return;
SetHtmlText(view.Text);
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == Label.TextProperty.PropertyName)
{
SetHtmlText(((HtmlLabel) sender).Text);
}
}
private void SetHtmlText(string text)
{
var encodedText = (((int)Build.VERSION.SdkInt) >= 24) ? Html.FromHtml(text, FromHtmlOptions.ModeLegacy) :
#pragma warning disable 618
// need this for backward compatability
Html.FromHtml(text);
#pragma warning restore 618
Control.MovementMethod = LinkMovementMethod.Instance;
Control.SetText(encodedText, TextView.BufferType.Spannable);
}
}
}
Your custom HtmlLabel class should be able to derive from the same thing on Android and iOS
namespace YourNameSpace
{
public class HtmlLabel : Label
{
}
}
The renderer for Android should look something like this
[assembly: ExportRenderer(typeof(HtmlLabel), typeof(HtmlLabelRenderer))]
namespace YourNameSpace.Droid
{
public class HtmlLabelRenderer : ViewRenderer<Label, TextView>
{
TextView _textView;
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (Element == null)
return;
if(Control == null)
{
_textView = new TextView(Context);
SetHtmlText(Element.Text);
SetNativeControl(_textView);
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (Element == null || Control == null)
return;
if (e.PropertyName == HtmlLabel.TextProperty.PropertyName)
{
SetHtmlText(Element.Text);
}
}
private void SetHtmlText(string text)
{
if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.N)
{
_textView.TextFormatted = Html.FromHtml(text, Android.Text.FromHtmlOptions.ModeCompact);
}
else
{
_textView.TextFormatted = Html.FromHtml(text);
}
}
}
}
And on iOS it should look very similar
[assembly: ExportRenderer(typeof(HtmlLabel), typeof(HtmlLabelRenderer))]
namespace YourNameSpace.iOS
{
public class HtmlLabelRenderer : ViewRenderer<Label, UITextView>
{
UITextView _textView;
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (Element == null)
return;
if(Control == null)
{
_textView = new UITextView();
SetHtmlText(Element.Text);
SetNativeControl(_textView);
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (Element == null || Control == null)
return;
if (e.PropertyName == HtmlLabel.TextProperty.PropertyName)
{
SetHtmlText(Element.Text);
}
}
private void SetHtmlText(string text)
{
var attr = new NSAttributedStringDocumentAttributes { DocumentType = NSDocumentType.HTML };
var nsError = new NSError();
_textView.Editable = false;
_textView.AttributedText = new NSAttributedString(text, attr, ref nsError);
_textView.DataDetectorTypes = UIDataDetectorType.All;
}
}
}
I tested that on Android and it worked, calling OnElementPropertyChanged when the text changed and everything. However, I don't have a mac at home to try the iOS Renderer so I'm just assuming it will function pretty much the same.

Get Camera captured images and create bitmap image

How to get camera captured images after native camera app exits ?
How to create an Bitmap image from the already existing SD card Jpeg image ?
I want to add this Bitmap to the screen.
ButtonField btn_Take_Pic = new ButtonField("Take a pic",Field.FIELD_HCENTER|FOCUSABLE)
{
protected boolean navigationClick(int status, int time) {
// TODO Auto-generated method stub
InvokeCameraScreen screen = new InvokeCameraScreen(CaptureImage.this);
screen.addCam();
UiApplication.getUiApplication().invokeLater (new Runnable() {
public void run()
{
//Perform screen changes here.
//Calling invalidate() on your screen forces the paint
//method to be called.
CaptureImage deal_Screen = new CaptureImage();
deal_Screen.invalidate();
}
});
return true;
}
};
Add body part of ImagePath() method
public void ImagePath(String path) {
try
{
Img_path = path;
EncodedImage.createEncodedImage(imgarr,0,imgarr.length);
Bitmap setimage = resizeBitmap(getBitmapFromFile(info.getImg_Path()),(int) (ScreenWidth *0.20),(int) (ScreenHeight *0.20));
Img_Field.setBitmap(setimage);
}
catch (Exception e) {
// TODO: handle exception
Dialog.alert("Ex path: " + e.toString());
}
}
implements ImagePath interface
public interface ImagePath {
public void ImagePath(String path);
}
public class InvokeCameraScreen implements FileSystemJournalListener {
private long lastUSN;
private String resultData, imagepath;
private VerticalFieldManager addToSCreen;
private boolean isAlreadeyExcuted = true;
private byte[] imageData;
private ImagePath pathImage;
public InvokeCameraScreen(ImagePath path) {
this.pathImage = path;
}
public void addCam() {
isAlreadeyExcuted = true;
getAddToSCreen().deleteAll();
startCam();
}
private void startCam() {
lastUSN = FileSystemJournal.getNextUSN();
UiApplication.getUiApplication().addFileSystemJournalListener(this);
try {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Invoke.invokeApplication(Invoke.APP_TYPE_CAMERA,
new CameraArguments());
}
});
} catch (Exception e) {
System.out.println("CheckinFormScreen Exception: " + e.toString());
}
}
private void closeCamera() {
System.out.println("Closing Cam");
EventInjector.KeyEvent inject = new EventInjector.KeyEvent(
EventInjector.KeyEvent.KEY_DOWN, Characters.ESCAPE, 0, 25);
inject.post();
try {
Thread.sleep(500);
} catch (Exception e) {
}
UiApplication.getUiApplication().removeFileSystemJournalListener(this);
System.out.println("Done with closing cam");
}
public byte[] getImageData() {
return imageData;
}
public void setImageData(byte[] imageData) {
this.imageData = imageData;
}
public String getImagepath() {
return imagepath;
}
public void setImagepath(String imagepath) {
this.imagepath = imagepath;
}
public void fileJournalChanged() {
try {
closeCamera();
} catch (Exception e) {
}
long USN = FileSystemJournal.getNextUSN();
for (long i = USN - 1; i >= lastUSN && i < USN; --i) {
FileSystemJournalEntry entry = FileSystemJournal.getEntry(i);
if (entry == null) {
break;
}
if (entry.getEvent() == FileSystemJournalEntry.FILE_ADDED) {
String path = entry.getPath();
if (path != null && path.indexOf(".jpg") != -1) {
if (isAlreadeyExcuted) {
isAlreadeyExcuted = false;
resultData = "file://" + path;
pathImage.ImagePath(resultData);
// ShowUploadImage(resultData);
EventInjector.KeyEvent inject = new EventInjector.KeyEvent(
EventInjector.KeyEvent.KEY_DOWN,
Characters.ESCAPE, 0, 25);
inject.post();
inject.post();
if (Display.getWidth() == 480
&& Display.getHeight() == 360
|| Display.getWidth() == 360
&& Display.getHeight() == 480) {
try {
Thread.sleep(500);
inject.post();
} catch (Exception e) {
}
}
}
}
return;
}
}
}
public VerticalFieldManager getAddToSCreen() {
if (addToSCreen == null) {
addToSCreen = new VerticalFieldManager();
addToSCreen.setPadding(10, 10, 10, 10);
}
return addToSCreen;
}
public void setAddToSCreen(VerticalFieldManager addToSCreen) {
this.addToSCreen = addToSCreen;
}
private void ShowUploadImage(String path) {
}
}
try this,
CAll Below Class Like:
EncodedImage result = NcCamera.getInstance().getPictureTaken();
//
This is class in which you can get Camera images.
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.media.Manager;
import javax.microedition.media.Player;
import javax.microedition.media.control.VideoControl;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.Screen;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
public class NcCamera extends MainScreen
{
private VideoControl videoControl;
private Field videoField;
public static EncodedImage pictureTaken = null;
private boolean initialized = false;
private boolean result;
public static boolean CAPTURING_DONE = true;
public static boolean CAPTURING_CANCELED = false;
private VerticalFieldManager main;
private static NcCamera instance;
CommonFunction cmn_fun;
public static byte[] raw;
public NcCamera()
{
super(NO_VERTICAL_SCROLL);
main = new VerticalFieldManager(USE_ALL_WIDTH | USE_ALL_HEIGHT)
{
// I wan't to force the backgound to black
public void paintBackground(Graphics g)
{
g.setBackgroundColor(0x000000);
g.clear();
}
};
super.add(main);
}
public void add(Field field)
{
main.add(field);
}
public EncodedImage getPictureTaken()
{
return pictureTaken;
}
public Screen getThisScreen()
{
return this;
}
public void reset()
{
pictureTaken = null;
result = CAPTURING_CANCELED;
}
public boolean showDialog()
{
result = CAPTURING_CANCELED;
UiApplication.getUiApplication().invokeAndWait(new Runnable()
{
public void run()
{
UiApplication.getUiApplication().pushModalScreen(getThisScreen());
if (pictureTaken != null)
result = CAPTURING_DONE;
}
});
return result;
}
public static NcCamera getInstance()
{
if (instance == null)
instance = new NcCamera();
return instance;
}
public void onDisplay() {
if (!initialized)
{
initializeCamera();
if (videoField!=null) add(videoField);
else {
LabelField sorry = new LabelField("Sorry, we cannot use camera right now.") {
// I need to force the label to be white colored to be visible above
// it's underlying manager (that is black).
public void paint(Graphics g) {
int color = g.getColor();
g.setColor(0xffffff);
super.paint(g);
g.setColor(color);
}
};
add(sorry);
}
initialized = true;
}
}
private void initializeCamera()
{
try {
// Create a player for the Blackberry's camera
Player player = Manager.createPlayer("capture://video?encoding=jpeg&width=1024&height=768");
// Set the player to the REALIZED state (see Player javadoc)
player.realize();
videoControl = (VideoControl) player.getControl("VideoControl");
if (videoControl != null)
{
videoField = (Field) videoControl.initDisplayMode(
VideoControl.USE_GUI_PRIMITIVE,
"net.rim.device.api.ui.Field");
videoControl.setDisplayFullScreen(true);
videoControl.setVisible(true);
}
player.start();
} catch (Exception e)
{
}
}
protected boolean invokeAction(int action)
{
boolean handled = super.invokeAction(action);
if (!handled)
{
switch (action)
{
case ACTION_INVOKE: // Trackball click
{
takePicture();
return true;
}
}
}
return handled;
}
public void takePicture()
{
try {
// Retrieve the raw image from the VideoControl and
// create a screen to display the image to the user.
raw = videoControl.getSnapshot(null);
// SaveImageSdcard(raw);
Bitmap img= Bitmap.createBitmapFromBytes(raw, 0, raw.length,3);
Constants.PICTURE_TAKEN=cmn_fun.resizeBitmap(img, 150, 150);
// save the picture taken into pictureTaken variable
pictureTaken = EncodedImage.createEncodedImage(raw, 0, raw.length);
result = CAPTURING_DONE;
close();
} catch (Exception e)
{
}
}
}
public boolean keyDown(int keycode,
int time) {
if (keycode == 1769472)
{ // escape pressed
reset();
close();
return true;
}
return super.keyDown(keycode, time);
}
}

How to save captured image in a folder in blackberry?

I am developing application which has camera functionality. i want to save that captured image in my project folder.Can any one help me please.
thanx in advance.
This below code may help you:
Add this to Main Screen which you want to show the camera:
captureImage=new MenuItem("Capture Images",10,100)
{
public void run()
{
synchronized (Application.getEventLock())
{
captureImage();
}
}
};
addMenuItem(captureImage);
The code for captureImage() method is:
private void captureImage()
{
try
{
player = javax.microedition.media.Manager.createPlayer("capture://video?encoding=jpeg&width=1024&height=768");
player.realize();
_videoControl = (VideoControl) player.getControl("VideoControl");
if (_videoControl != null)
{
Field videoField = (Field) _videoControl.initDisplayMode (VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field");
_videoControl.setDisplayFullScreen(true);
_videoControl.setVisible(true);
player.start();
if(videoField != null)
{
add(videoField);
}
}
}
catch(Exception e)
{
if(player!=null)
{
player.close();
}
Dialog.alert(e.toString());
}
}
The below code is save the image into the sdcard or device card. Override the invokeAction(int action) Method
protected boolean invokeAction(int action)
{
boolean handled = super.invokeAction(action);
if(SdcardTest.SdcardAvailabulity())//I am checking here that the sdcard is there of or not.....?
{
//PATH = "file:///SDCard/BlackBerry/pictures/"+"Image_"+System.currentTimeMillis()+".jpg";
PATH = System.getProperty("fileconn.dir.memorycard.photos")+"Image_"+System.currentTimeMillis()+".jpg";//here "str" having the current Date and Time;
}
else
{
PATH = System.getProperty("fileconn.dir.photos")+"Image_"+System.currentTimeMillis()+".jpg";
}
if(!handled)
{
if(action == ACTION_INVOKE)
{
try
{
byte[] rawImage = _videoControl.getSnapshot(null);
fileconn=(FileConnection)Connector.open(PATH);
if(fileconn.exists())
{
fileconn.delete();
}
fileconn.create();
OutputStream os=fileconn.openOutputStream();
os.write(rawImage);
fileconn.close();
os.close();
Status.show("Image is Captured",200);
if(player!=null)
player.close();
}
catch(Exception e)
{
if(player!=null)
{
player.close();
}
if(fileconn!=null)
{
try
{
fileconn.close();
}
catch (IOException e1)
{
//if the action is other than click the trackwheel(means go to the menu options) then we do nothing;
}
}
}
}
}
return handled;
}
try this for image snap
Note: you can not store in resource folder you can only store in SDcard
class screen extends MainScreen implements FieldChangeListener
{
private VideoControl vc;
private String encoding;
private Player p;
private Field viewFinder;
private BitmapField bitmapField;
private ButtonField btn;
public screen() {
btn=new ButtonField("snap",Field.FOCUSABLE);
btn.setChangeListener(this);
add(btn);
}
public void fieldChanged(Field field, int context) {
if(field==btn)
{
try{
p = Manager.createPlayer("capture://video");
p.realize();
p.prefetch();
p.start();
vc = (VideoControl) p.getControl("VideoControl");
viewFinder = (Field)vc.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field");
vc.setVisible(true);
final String imageType = "encoding=jpeg&width=640&height=480&quality=superfine";
UiApplication.getUiApplication().invokeLater(new Runnable(){
public void run(){
byte[] image = vc.getSnapshot(imageType);
FileConnection conn = (FileConnection)Connector.open("file:///store/home/user/pictures/"+System.currentTimeMillis()+".jpeg", Connector.READ_WRITE);
conn.create();
OutputStream out = conn.openOutputStream();
out.write(image);
out.flush();
out.close();
conn.close();
Bitmap image1 = Bitmap.createBitmapFromBytes(imageBytes, 0, imageBytes.length, 4);
bitmapField.setBitmap(image1);
add(bitmapField);
}
});
} catch (Exception me){
}
}
}
}
for more operations please use this
http://supportforums.blackberry.com/rim/attachments/rim/java_dev#tkb/226/1/SnapshotSample.zip
if you want to save an image from camera to your device you can use the following code.
try
{
focusControl.startAutoFocus();
byte[] image = videoControl.getSnapshot(null);
String message = "Captured "+image.length+" bytes of JPG data";
debug(message);
FileConnection conn = (FileConnection)Connector.open("file:///store/home/user/pictures/"+(new Date()).getTime()+".jpg", Connector.READ_WRITE);
conn.create();
OutputStream out = conn.openOutputStream();
out.write(image);
out.flush();
out.close();
conn.close();
Dialog.alert(message);
}
catch (Exception e) {
Dialog.alert("Capture failed due to: "+e.getMessage());
}
If you want to save the images in your Project/res or Project/src during runtime, you cant do that.
You can save image in SDcard/device.
Why would you want to save it in your project source?

Resources