My Target:
Get one photo from camera or gallery, then set it to imageViewA
Add a draggable mask imageViewB on top of imageViewA
Users drag the mask imageViewB to anywhere in imageViewA
Users then click the save button
A combined bitmap of imageViewA and imageViewB should be created
My Problem:
Everything works fine, except that the imageViewB in the combined bitmap is not positioned appropriately (see the attached picture)
Code (MainActivity.java):
public class MainActivity extends ActionBarActivity {
Bitmap bmMask = null;
Bitmap bmOriginal = null;
Bitmap bmCombined = null;
ImageView normalImgView;
ImageView maskImgView;
ImageView combinedImgView;
static final int REQUEST_TAKE_PHOTO = 55;
static final int REQUEST_LOAD_IMAGE = 60;
String currentImagePath;
static final String TAG = "mover";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
combinedImgView = (ImageView) findViewById(R.id.combinedImgView);
normalImgView = (ImageView) findViewById(R.id.normalImgView);
maskImgView = (ImageView) findViewById(R.id.maskImgView);
bmMask = ((BitmapDrawable) maskImgView.getDrawable()).getBitmap();
Button addBtn = (Button) findViewById(R.id.addBtn);
addBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bmCombined = ProcessingBitmap();
if(bmCombined!=null){
combinedImgView.setImageBitmap(bmCombined);
}
else {
Log.d(MainActivity.TAG, "combined bm is null");
}
}
});
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(MainActivity.TAG, "clicked");
getImageFromCameraIntent();
}
});
MultiTouchListener mTouchListener = new MultiTouchListener();
mTouchListener.isRotateEnabled = false;
// mTouchListener.isTranslateEnabled = false;
mTouchListener.isScaleEnabled = false;
maskImgView.setOnTouchListener(mTouchListener);
}
// take image from camera
private void getImageFromGalleryIntent() {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, REQUEST_LOAD_IMAGE);
}
// take image from camera
private void getImageFromCameraIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(this.getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
// create a image file for storing full size image taken from camera
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
currentImagePath = image.getAbsolutePath();
Log.d(MainActivity.TAG, "photo path: " + currentImagePath);
return image;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == Activity.RESULT_OK) {
// photo returned from camera
// update UI
updatePhotoView(currentImagePath);
} else if (requestCode == REQUEST_LOAD_IMAGE && resultCode == Activity.RESULT_OK) {
// photo returned from gallery
// update UI
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = this.getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
updatePhotoView(picturePath);
} else {
Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
}
}
// scale down the image, then display it to image view
private void updatePhotoView(String photoPath) {
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(photoPath, bmOptions);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(photoPath, bmOptions);
bmOriginal = bitmap;
normalImgView.setImageBitmap(bmOriginal);
}
private Bitmap ProcessingBitmap(){
Bitmap newBitmap = null;
int w;
w = bmOriginal.getWidth();
int h;
h = bmOriginal.getHeight();
Bitmap.Config config = bmOriginal.getConfig();
if(config == null){
config = Bitmap.Config.ARGB_8888;
}
newBitmap = Bitmap.createBitmap(w, h, config);
Canvas newCanvas = new Canvas(newBitmap);
newCanvas.drawBitmap(bmOriginal, 0, 0, null);
Paint paint = new Paint();
float left = maskImgView.getLeft();
float top = maskImgView.getTop();
Log.d(MainActivity.TAG, "left is " + left);
Log.d(MainActivity.TAG, "top is " + top);
newCanvas.drawBitmap(bmMask, left, top, paint);
return newBitmap;
}
}
Code (xml)
<RelativeLayout
android:id="#+id/imgSection"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5"
android:background="#android:color/background_dark">
<TextView
android:id="#+id/before_combie_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="before combine image"
android:textColor="#android:color/white"/>
<ImageView
android:id="#+id/normalImgView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/maskImgView"
android:layout_centerInParent="true"
android:src="#drawable/daffodils"
android:layout_width="100dp"
android:layout_height="60dp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5"
android:background="#android:color/holo_blue_dark">
<TextView
android:id="#+id/after_combie_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="after combine image"
android:textColor="#android:color/white"/>
<ImageView
android:id="#+id/combinedImgView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Take Photo"
android:layout_gravity="center_horizontal"/>
<Button
android:id="#+id/addBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get Combined Photo"
android:layout_gravity="center_horizontal"/>
My Thought:
I guess the positioning issue occurs in the few lines of code listed below. I just have no idea how to get it right, yet.
float left = maskImgView.getLeft();
float top = maskImgView.getTop();
newCanvas.drawBitmap(bmMask, left, top, paint);
Any help is appreciated!
In this case both of image view in same layout for ex.
<RelativeLayout
android:id="#+id/imgSection"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5"
android:background="#android:color/background_dark">
<TextView
android:id="#+id/before_combie_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="before combine image"
android:textColor="#android:color/white"/>
<ImageView
android:id="#+id/normalImgView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/maskImgView"
android:layout_centerInParent="true"
android:src="#drawable/daffodils"
android:layout_width="100dp"
android:layout_height="60dp" />
------->
RelativeLayout imgSection;
....
....
//On the save button click
imgSection.buildDrawingCache();
imgSection.getDrawingCache();//it will return combine image bitmap
I hope this will help.....
Related
Good Day
I'm trying to capture an image with camera when I press the Button,then save it in Sqllite and then display it in gridview..
but after I capture the image it doesn't appear in the grid view :/ no error appear in logcat except nothing displayed in gridview
can anyone help?
here is my code
public class CameraFragment extends Fragment {
public static final int MEDIA_TYPE_IMAGE = 1;
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
private static final String IMAGE_DIRECTORY_NAME = "Myfiles";// directory name to store captured images
private static String mCurrentPhotoPath; // file path to the last image captured
View view;
private Uri fileUri;// file url to store image
private GridView myGridView;
private ImageListAdapter adapter;
private List<Images> myLists;// image list
Images images;
DatabaseAdapter DBadapter;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {
// Inflate the layout for this fragment
view = inflater
.inflate(R.layout.fragment_camera, container, false);
} catch (InflateException e) {
/* map is already there, just return view as it is */
e.printStackTrace();
}
if (view != null)
init();
return view;
}
// initialize all the variables
private void init() {
DatabaseAdapter DBadapter =new DatabaseAdapter(getActivity());
DBadapter.open();
myLists = new ArrayList<Images>();
myLists=DBadapter.getImagesList();
adapter = new ImageListAdapter(getActivity(), R.layout.img_list_view, myLists);
// imageView = (ImageView) view.findViewById(R.id.imageListView);
Button myButton = (Button) view.findViewById(R.id.camerabutton);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);// create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE); // start the image capture Intent
}
});
myGridView = (GridView) view.findViewById(R.id.gridView);
myGridView.setAdapter(adapter);
/**
* Create a file Uri for saving an image or video
*/
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
/**
* returning image /
*/
private static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
mediaStorageDir.mkdirs();
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
+ IMAGE_DIRECTORY_NAME + " directory");
//return null;
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 1:
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
//file path of captured image
String filePath = cursor.getString(columnIndex);
//file path of captured image
File f = new File(filePath);
String filename = f.getName();
cursor.close();
DBadapter.insertImage(images); //insaert image to database
myLists=DBadapter.getImagesList();
adapter = new ImageListAdapter(getActivity(), R.layout.img_list_view, myLists);
myGridView.setAdapter(adapter);
myGridView.invalidateViews();
break;
}
case 2:
if (resultCode == getActivity().RESULT_CANCELED) {
// user cancelled Image capture
Toast.makeText(getActivity(), "User cancelled image capture", Toast.LENGTH_SHORT)
.show();
}
else {
// failed to capture image
Toast.makeText(getActivity(), "Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
} break;
}}
}
here is xml :
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.labon.invoicemanger.CameraFragment">
<!-- TODO: Update blank fragment layout --> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="My Invoice"
android:layout_gravity="center"
android:layout_margin="20dp"
android:id="#+id/textView16"
android:textColor="#color/colorPrimary"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<GridView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/gridView"
android:layout_above="#+id/camerabutton"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:numColumns="auto_fit"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add New Invoice"
android:textSize="18dp"
android:textStyle="bold"
android:textColor="#android:color/white"
android:id="#+id/camerabutton"
android:drawableRight="#drawable/screenshot"
android:background="#color/colorAccent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<!--android:drawableRight="#drawable/screen_shot"--> </RelativeLayout> </FrameLayout>
I think you should refresh your grid view when you save images in sqlite.
see the following link, it might help you:
click here!
you should use invalidateViews() method.
I am learning android. I am trying to take a picture from the camera and then save it in a specific folder "Myimages" and display the image in ImageView. When I capture the image from the camera the image is saved inthe myimage folder, but it is not getting displayed in ImageView. Ülease suggest me a solution.
1.layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="#+id/path"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="#+id/image_view"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerVertical="true"
android:layout_marginLeft="50dp"
android:layout_toRightOf="#+id/path"
android:maxHeight="42dp"
android:maxWidth="42dp"
android:scaleType="fitCenter" />
</RelativeLayout>
2.Mainactivity
public class MainActivity extends Activity {
private static final int REQUEST_CODE = 2;
File folder;
File imagefile;
TextView imagepath;
ImageView imageview;
Uri imageuri;
Intent intent;
String folderpath;
int ct = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageview = (ImageView) findViewById(R.id.image_view);
imagepath = (TextView) findViewById(R.id.path);
createfolder();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_settings) {
imagefile = getimagefile(folder);
imagepath.setText(imagefile.getAbsolutePath().toString());
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imagefile));
startActivityForResult(intent, REQUEST_CODE);
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
Bitmap bp = (Bitmap) intent.getExtras().get("data");
// imageview.setImageBitmap(bp);
imageview.setImageURI(Uri.fromFile(imagefile));
}
public File getimagefile(File folder) {
File mediafile;
mediafile = new File(folder.getAbsoluteFile() + File.separator + "img_"
+ ct + ".jpeg");
ct++;
return mediafile;
}
public File createfolder() {
folder = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
+ "/Myimages");
if (!folder.exists()) {
folder.mkdir();
}
return folder;
}
}
Try converting the Bitmap into a BitmapDrawable, and then use SetImageDrawable.
Data Intent find through onActivityResult there you can get image path and make File then make uri to setting imageUri in imageView.
String mTempImagePath = data.getData();
File file = new File(mTempImagePath .toString());
Uri uri = Uri.fromFile(file);
imageview.setImageURI(uri);
// try this way,hope this will help you...
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
imageview.setImageBitmap(decodeFile(imagefile.getAbsolutePath()));
}
public Bitmap decodeFile(String path) {
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 100;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >= REQUIRED_SIZE)
scale *= 2;
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeFile(path, o2);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
Tried many methods, but did not reach a positive outcome.
In TableLayout has ImageView:
<TableLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/photo_layout_background"
android:stretchColumns="*" >
<TableRow
android:background="#color/photo_layoutrow_background"
android:layout_weight="1"
android:layout_marginBottom="4dp"
android:gravity="center" >
<ImageView
android:id="#+id/photo1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginRight="4dp"
android:src="#drawable/icon_photo"
android:background="#color/photo_background"
android:clickable="true"
android:onClick="addPhoto_Click"/>
When you click on ImageView offer standard procedure for obtaining pictures and the file is saved on the SD card:
public void addPhoto_Click(View v){
select_add_photo_id = v.getId();
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, generateFilePhotoUri());
startActivityForResult(takePictureIntent, CAMERA_RESULT);
}
#SuppressLint("SimpleDateFormat")
private Uri generateFilePhotoUri() {
File file = null;
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
file = new File(MEDIA_PATH + String.valueOf(id) + File.separator + timeStamp + ".jpg");
select_add_photo_file = file.getAbsolutePath();
return Uri.fromFile(file);
}
The photo is saved normally stored in variables select_add_photo_id id ImageView on which tapped the select_add_photo_file variable holds the full path to the file photo.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_RESULT) {
if (resultCode == RESULT_OK){
ImageView imgView = (ImageView) findViewById(select_add_photo_id);
imgView.setImageDrawable(Drawable.createFromPath(select_add_photo_file));
}
}
}
But when the file is only get ImageView ImageView with background and increased size. Photography is not loaded. There are no errors.
As still set photos?
after take a phone, in onActivityResult, data.getData may be null, in this case, try data.getExtras()
Bitmap photo = null;
Uri photoUri = data.getData();
String filePath = "";
if (photoUri != null) {
//mFilePath = getRealPathFromURI(photoUri);
filePath = getRealPathFromURI(photoUri);
photo = BitmapFactory.decodeFile(photoUri.getPath());
}
if (photo == null) {
Bundle extra = data.getExtras();
if (extra != null) {
photo = (Bitmap)extra.get("data");
...
I am new to android development and I am facing an issue when I capture an image from camera, it doesn't show up in the gridview immediately, if I refresh the activity or reload it than it is appearing in the gridview.
I have searched a lot and implemented various solutions but no one worked for me, please advice, following is my code.
My xml file is as:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/userHeader"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<include
android:layout_width="fill_parent"
android:layout_height="wrap_content"
layout="#layout/header_user" />
</RelativeLayout>
<TableLayout
android:layout_below="#id/userTable"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:stretchColumns="*" >
<TableRow android:id="#+id/historyDateRow">
<TextView android:text="#string/historyDateCaption" style="#style/captionStyle" />
<TextView android:id="#+id/viwHistoryDate" style="#style/captionStyle" />
</TableRow>
<TableRow android:id="#+id/historyUpdateDateRow">
<TextView android:text="#string/historyUpdateDateCaption" style="#style/captionStyle" />
<TextView android:id="#+id/viwHistoryUpdateDate" style="#style/captionStyle" />
</TableRow>
<TableRow android:layout_marginTop="2dp">
<TextView android:text="#string/historyCaption" style="#style/captionStyle" />
<TextView android:text="" style="#style/captionStyle" />
</TableRow>
<EditText
android:id="#+id/txtHistory"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginTop="5dp"
android:scrollbars="vertical"
android:gravity="top"
android:layout_marginRight="5dp" android:layout_marginLeft="5dp"
android:inputType="textMultiLine" />
<GridView
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:layout_weight="1"
android:gravity="center"/>
<Button android:id="#+id/btnSave"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp" android:layout_marginLeft="5dp"
android:text="#string/save"/>
<Button android:id="#+id/btnCapture"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp" android:layout_marginLeft="5dp"
android:text="Capture"/>
</TableLayout>
</RelativeLayout>
and in my java file I have code like:
String userId=null;
String historyId = null;
private Uri outputFileUri;
ImageAdapter myImageAdapter;
File root = null;
final String filesPath = Environment.getExternalStorageDirectory() + File.separator + "MyProj" + File.separator+ "Images" + File.separator;
private List<String> listOfImagesPath;
Boolean needsRefresh = false;
GridView gridview = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.casehistory);
GlobalVariables gv = ((GlobalVariables)getApplicationContext());
userId=gv.getsUserId();
historyId=getIntent().getStringExtra(ListHistory.ID_History);
gridview = (GridView) findViewById(R.id.gridview);
myImageAdapter = new ImageAdapter(this);
gridview.setAdapter(myImageAdapter);
String targetPath = "";
if(historyId == null)
{
targetPath = filesPath + userId + File.separator;
root = new File(filesPath + userId + File.separator);
}
else
{
targetPath = filesPath + userId + File.separator + historyId + File.separator;
root = new File(filesPath + userId + File.separator + historyId + File.separator);
gv.setsHistoryId(historyId);
}
root.mkdirs();
File targetDirector = new File(targetPath);
File[] files = targetDirector.listFiles();
if(files!=null)
{
for (File file : files){
myImageAdapter.add(file.getAbsolutePath());
}
}
Button btCapture=(Button)findViewById(R.id.btnCapture);
btCapture.setOnClickListener(onCapture);
}
than I have onCapture as:
private View.OnClickListener onCapture=new View.OnClickListener() {
public void onClick(View v) {
openImageIntent();
}
};
than my openImageIntent is as:
private void openImageIntent() {
// Determine Uri of camera image to save.
final String fname = "img_"+ System.currentTimeMillis() + ".jpg";
final File sdImageMainDirectory = new File(root, fname);
outputFileUri = Uri.fromFile(sdImageMainDirectory);
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for(ResolveInfo res : listCam) {
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
cameraIntents.add(intent);
}
// Filesystem.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
startActivityForResult(chooserIntent, 212);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
//CommonHelper.ShowErrorMessage("Result Code: " + String.valueOf(resultCode), CaseHistory.this);
if(resultCode == RESULT_OK)
{
//CommonHelper.ShowErrorMessage("Request Code: " + String.valueOf(requestCode), CaseHistory.this);
if(requestCode == 212)
{
final boolean isCamera;
if(data == null)
{
isCamera = true;
}
else
{
final String action = data.getAction();
if(action == null)
{
isCamera = false;
}
else
{
isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
}
}
Uri selectedImageUri;
if(isCamera)
{
selectedImageUri = outputFileUri;
}
else
{
selectedImageUri = data == null ? null : data.getData();
}
myImageAdapter.add(selectedImageUri.toString());
//GridView gridview = (GridView) findViewById(R.id.gridview);
//gridview.setAdapter(myImageAdapter);
myImageAdapter.notifyDataSetChanged();
gridview.invalidateViews();
gridview.setAdapter(myImageAdapter);
needsRefresh = true;
//CommonHelper.ShowErrorMessage("Image URI: " + selectedImageUri.toString(), CaseHistory.this);
//CommonHelper.ShowErrorMessage("Extra Data URI: " + data.getExtras().get("data"), CaseHistory.this);
}
}
}
and in end my Image adapter is as:
public class ImageAdapter extends BaseAdapter {
private Context mContext;
ArrayList<String> itemList = new ArrayList<String>();
public ImageAdapter(Context c) {
mContext = c;
}
void add(String path){
itemList.add(path);
}
#Override
public int getCount() {
return itemList.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(220, 220));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
Bitmap bm = decodeSampledBitmapFromUri(itemList.get(position), 220, 220);
imageView.setImageBitmap(bm);
return imageView;
}
public Bitmap decodeSampledBitmapFromUri(String path, int reqWidth, int reqHeight) {
Bitmap bm = null;
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(path, options);
return bm;
}
public int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
}
I have been struggling hard with it for last few days and have been trying different solutions from web but all in vain.
Can any body please help me in it?
Humble Request This is my first android project as well as Java project, so if anyone have time and want to feed back on the way I am coding is more than welcome.
Thanks in advance.
Everything seems ok to me exceptselectedImageUri.toString() this.
Just replace selectedImageUri.toString() with selectedImageUri.getPath() and you should be good.
When you call toString() on any object what it will try do is give you information about that object as a whole. In your case when you are calling toString() on URI, it will not give you exact path to that file instead it will give something like "file:///storage/emulated/0/MyProj/Images/111/222/img_1388856542838.jpg" this.And since it's not an absolute filepath that's why decodeFile is not working in your adapter. On the other hand when you restart your activity you are dealing with absolute filepath with getAbsolutePath() and that is why after restarting it is working. So to get the path from URI object you have to call getPath().
I have found some useLess code there, Just do either, That may be a problem
selectedImageUri.toString() will not give you the path of the image you want it is retrieved using selectedImageUri.getPath()
myImageAdapter.notifyDataSetChanged(); // This will try to load your new Image
gridview.invalidateViews(); // then you are refreshing views and setting the adapter again below
gridview.setAdapter(myImageAdapter);
use just
myImageAdapter.notifyDataSetChanged();
This question already has answers here:
How to retrieve the dimensions of a view?
(16 answers)
Closed 3 years ago.
I, I'm starting to explore Android and I am kind of stuck with my first issue.
My ImageView is returning 0 on width and height after rotating the screen. It works fine the first time when I upload a photo, but once I flip the screen it returns 0. I've tried to obtain it in the onResume and onRestoresavedInstance methods, but I've failed. Does anyone have an idea how to solve the problem?
Thank you in advance. :)
Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="#+id/text_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/email" />
<EditText
android:id="#+id/text_nickname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/nickname" />
<Button
android:id="#+id/button_take_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="takePhoto"
android:text="#string/photo_button" />
<ImageView
android:id="#+id/image_viewer"
android:layout_width="match_parent"
android:contentDescription="#string/photo_taken"
android:background="#android:color/black"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="top"
android:adjustViewBounds="true" />
</LinearLayout>
Code
public class MainActivity extends Activity {
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private String fileUri;
private ImageView mImageView;
private EditText nickTextView;
private EditText mailTextView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
}
#Override
public void onResume() {
super.onResume();
try {
if (this.fileUri != null) {
setPic();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putString("fileUri", this.fileUri);
savedInstanceState.putString("nick", this.nickTextView.getText()
.toString());
savedInstanceState.putString("email", this.mailTextView.getText()
.toString());
super.onSaveInstanceState(savedInstanceState);
}
// onRestoreInstanceState
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
this.fileUri = savedInstanceState.getString("fileUri");
this.nickTextView.setText(savedInstanceState.getString("nick"));
this.mailTextView.setText(savedInstanceState.getString("email"));
}
public void takePhoto(View view) {
if (checkCameraHardware(this)) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
this.fileUri = getOutputMediaFilePath();
File temp = new File(fileUri);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(temp));
startActivityForResult(intent,
MainActivity.CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
} else {
System.out
.println("This hardware does not support camera features!!!");
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// galleryAddPic();
try {
setPic();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (resultCode == RESULT_CANCELED) {
System.out.println("User cancelled the image capture");
} else {
System.out.println("Image capture failed, advise user");
}
}
}
private void initUI() {
// Get the image view
mImageView = (ImageView) findViewById(R.id.image_viewer);
// Get the text views
nickTextView = (EditText) findViewById(R.id.text_nickname);
mailTextView = (EditText) findViewById(R.id.text_email);
}
private String getOutputMediaFilePath() {
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss")
.format(new Date());
String imageFileName = "liftoff_" + timeStamp + ".jpg";
File image = new File(storageDir, imageFileName);
return image.getAbsolutePath();
}
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(fileUri);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
private void setPic() throws Exception {
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileUri, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Get the dimensions of the View
int targetH = mImageView.getHeight();
int targetW = mImageView.getWidth();
// Put correct orientation
Matrix matrix = new Matrix();
ExifInterface exif = new ExifInterface(this.fileUri);
String orientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
if (orientation.equals(ExifInterface.ORIENTATION_NORMAL)) {
// Do nothing. The original image is fine.
} else if (orientation.equals(ExifInterface.ORIENTATION_ROTATE_90 + "")) {
photoW = bmOptions.outHeight;
photoH = bmOptions.outWidth;
matrix.postRotate(90);
} else if (orientation
.equals(ExifInterface.ORIENTATION_ROTATE_180 + "")) {
matrix.postRotate(180);
} else if (orientation
.equals(ExifInterface.ORIENTATION_ROTATE_270 + "")) {
matrix.postRotate(270);
photoW = bmOptions.outHeight;
photoH = bmOptions.outWidth;
}
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(fileUri, bmOptions);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), matrix, true);
mImageView.setImageBitmap(resizedBitmap);
}
Make sure that the View has finished its layout process. Give this a try.