Taking 3 photos with StartActivityForResults - android

I would appreciate some help, I want to take three photos under the same Intent with startActivityForResults() within a loop, and getting back onActivityResult () which prints those three photos in three imageviews, with MarshMallow, and its specific permissions (I think this is not the issue and it should be solved in my code),
The issue is that the application takes those three pictures, and makes the ArrayList or URIs, but it does not arrive to actually printing those three photos in the three imageviews,
Here is my code, thanks in advance,
-----------------
MainActivity.java
-----------------
public class MainActivity extends AppCompatActivity {
//private int numFotos = 1;
//private Bitmap bitmap;
private ArrayList <Uri> uriFiles;
private ImageView imageView1, imageView2,imageView3;
private Button button_takePics;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_takePics = (Button) findViewById(R.id.Butt_tiraFotos);
imageView1 = (ImageView) findViewById(R.id.image_1);
imageView2 = (ImageView) findViewById(R.id.image_2);
imageView3 = (ImageView) findViewById(R.id.image_3);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
button_takePics.setEnabled(false);
ActivityCompat.requestPermissions(this, new String[]
{ Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 0) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
button_takePics.setEnabled(true);
}
}
}
public void takePictures(View view){
uriFiles = new ArrayList<>();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
for (int i=1; i<4; i++){
uriFiles.add(Uri.fromFile(getOutputMediaFile()));
intent.putParcelableArrayListExtra(MediaStore.EXTRA_OUTPUT,uriFiles);
startActivityForResult(intent, 100);
}
}
private static File getOutputMediaFile() {
File mediaStorageDir=null;
File formattedFile = null;
mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "CameraDemo");
if (!mediaStorageDir.exists()){
if (!mediaStorageDir.mkdirs()){
Log.d("CameraDemo", "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
formattedFile= new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
return formattedFile;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100) {
if (resultCode == RESULT_OK) {
uriFiles = data.getParcelableArrayListExtra(MediaStore.EXTRA_OUTPUT);
// AQUI EMPIEZA EL PROBLEMA ////////
imageView1.setImageURI(uriFiles.get(0));
imageView2.setImageURI(uriFiles.get(1));
imageView3.setImageURI(uriFiles.get(2));
}
}
}
}
-------------------
activity_main.xml
-------------------
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
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"
android:orientation="vertical"
tools:context="com.example.faustocheca.photochooseshare.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="18dp"
android:layout_marginTop="18dp"
android:textSize="18sp"
android:text="Tira, escoge y comparte Fotos" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:hint="Tira 3 Fotos"
android:id="#+id/Butt_tiraFotos"
android:onClick="takePictures"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="48dp"
android:orientation="horizontal"
>
<ImageView
android:id="#+id/image_1"
android:layout_weight="1"
android:layout_width="80dp"
android:layout_height="120dp"
android:layout_margin="1dp"
android:background="#feafea"/>
<ImageView
android:id="#+id/image_2"
android:layout_weight="1"
android:layout_width="80dp"
android:layout_height="120dp"
android:layout_margin="1dp"
android:background="#feafea"/>
<ImageView
android:id="#+id/image_3"
android:layout_weight="1"
android:layout_width="80dp"
android:layout_height="120dp"
android:layout_margin="1dp"
android:background="#feafea"/>
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:hint="Comparte"
android:id="#+id/Butt_comparte"
/>
</LinearLayout>

This will not work; a single startActivityForResult will result in a single call to onActivityResult.
There's no contract in the ACTION_IMAGE_CAPTURE documentation or elsewhere in the system that says that you can issue it multiple times and get one result with 3 URIs.
You'll have to loop it so that you fire one intent, wait for the result, fire the second intent, wait for the result, etc.
You may be able to fire the 3 intents in a loop like this, but I'm not sure I'd trust that the responding camera application would actually be invoked 3 times. But even so, you'll receive 3 separate onActivityResult calls, if that works.

Related

How to populate and maintain listView with images?

I want to design a listView such that when a user adds a photo, it will automatically update the listView with the name of the image and it's thumbnail. However my current attempts don't even render the image. Is it possible to dynamically set the ImageView for each cell of a listView and have it be updated when I add a new element to the Adapter?
XML for listView and add button:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".Photos"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/view_album_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<ListView android:layout_marginTop="?android:attr/actionBarSize"
android:id="#+id/photos_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:choiceMode="singleChoice"
android:listSelector="#android:color/darker_gray" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/add_photo_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="25dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:src="#drawable/plus"/>
</RelativeLayout>
Activity:
public class ViewAlbum extends AppCompatActivity {
public Album activeAlbum;
private ListView photoList;
private ArrayList<String> currentPhotos = new ArrayList<String>();
private ArrayAdapter<String> adapter;
private int currentSelected = -1;
public static final int PICK_IMAGE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_album);
final Context context = getApplicationContext();
Toolbar albumBar = findViewById(R.id.view_album_bar);
setSupportActionBar(albumBar);
photoList = findViewById(R.id.photos_list);
Bundle bundle = getIntent().getExtras();
String albumName = bundle.getString("album_name");
activeAlbum = Album.loadAlbum(this.getFilesDir().getPath()+"/"+albumName+".txt");
for(Photo photo: activeAlbum.photos){
ImageView thumbnail = findViewById(R.id.photo_thumbnail);
if(thumbnail == null){
System.out.println("why?");
//Don't understand why it is null, can't set image
}
currentPhotos.add(photo.name);
}
adapter = new ArrayAdapter<String>(this, R.layout.photo_cell,
R.id.photo_name,currentPhotos);
photoList.setAdapter(adapter);
photoList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
currentSelected = position;
}
});
FloatingActionButton addPhotoBtn = (FloatingActionButton)findViewById(R.id.add_photo_btn);
addPhotoBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE && resultCode == Activity.RESULT_OK
&& data != null && data.getData() != null) {
Uri uri = data.getData();
Photo newPhoto = new Photo("name", uri.getPath());
activeAlbum.photos.add(newPhoto);
activeAlbum.saveAlbum();
}
}
Each ListView Cell:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:background="?android:attr/activatedBackgroundIndicator">
<LinearLayout android:id="#+id/thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dip"
android:layout_alignParentLeft="true"
android:layout_marginRight="5dip">
<ImageView
android:id="#+id/photo_thumbnail"
android:layout_width="106dp"
android:layout_height="77dp" />
</LinearLayout>
<TextView
android:id="#+id/photo_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="25dp"
android:text="Album Name"
android:textColor="#0984e3"
android:textSize="25dip"
android:textStyle="bold"
android:typeface="sans" />
</RelativeLayout>
Firstly, I think album.photo is not the same array as the array you passed when you create the adapter (currentPhotos). So adding new Photo to album.photo does not reflect that item in the listView.
Secondly, as user dev points out, whenever you change the data you need to tell the adapter by adapter.notifyDataSetChanged(). However in your case, you always add to the end i think it is better to call adapter.notifyDataInserted(currentPhotos.size() - 1)
When you get result on OnActivityResult() add it to currentPhotos,
then call notifyDataSetChanged()
If you are working with images which are locally stored or on the web. Using a lib like implementation 'com.squareup.picasso:picasso:2.71828' is probably a good idea as it can handle image and URL based exception and had a catch of the data so that it is easier to open apps memory can be used minimally.

How to add 2 imageviews in layout dynamically in android

I am developing the Android app in which i want to add 2 imagview at time in layout.The flow is in layout there is one imageview added for taking photo via camera when user take photo from camera when I get the image from camera I will show it in that imageview and that imageview has one cross ImageButton on it's right corner which will get visible when image gets loaded and same thing will happen for another imageview which i want to add when user click photo but i dont know how to add this dynamically. I search for answer but there is only one imageview is added in the layout.Please help me out with this issue.
i want it like this
as show in this image the imageview has cross button on it
as per the solution given by Vijendra i updated my xml and java code but having
error
java.lang.IllegalArgumentException: Cannot add a null child view to a ViewGroup
here is my main.xml:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/bicycle_broken_layout">
<EditText
android:id="#+id/et_moreinfo_broken_bike"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginTop="15dp"
android:hint="#string/more_info"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:background="#color/ch_bg"
android:paddingTop="5dp"
android:lines="3"
android:gravity="top|left"
android:inputType="textMultiLine"/>
<RelativeLayout
android:id="#+id/broken_image_photos"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/et_moreinfo_broken_bike"
android:layout_marginTop="20dp">
</RelativeLayout>
<Button
android:id="#+id/btn_submit_report"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/broken_image_photos"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_centerHorizontal="true"
android:background="#color/bg_main"
android:text="#string/submit_button"
android:textSize="17sp"
android:textColor="#color/white"
android:padding="15dp"/>
</RelativeLayout>
and here is mainactivity.java
public class Broken_Report_Activity extends AppCompatActivity implements
View.OnClickListener {
private EditText broken_bike_number,broken_bike_location,more_info;
private Button barcode_scanner,location;
private Button submit_report;
private CheckBox seat,pedals,breaks,lock,chain,tier;
private Imageview_add_dynamically photo1,close_photo,framlayout;
RelativeLayout broken_image_layout;
private boolean Isphoto1=false,Isphoto2=false,Isphoto3=false;
private static final int CAMERA_REQUEST = 1888;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broken_report);
broken_bike_number = (EditText)findViewById(R.id.et_broken_bike_number);
broken_bike_location =
(EditText)findViewById(R.id.et_broken_bike_location);
more_info = (EditText)findViewById(R.id.et_moreinfo_broken_bike);
submit_report = (Button)findViewById(R.id.btn_submit_report);
seat = (CheckBox)findViewById(R.id.ch_seat);
lock = (CheckBox)findViewById(R.id.ch_lock);
chain = (CheckBox)findViewById(R.id.ch_chain);
breaks = (CheckBox)findViewById(R.id.ch_break);
pedals = (CheckBox)findViewById(R.id.ch_pedals);
tier = (CheckBox)findViewById(R.id.ch_tire);
broken_image_layout =
(RelativeLayout)findViewById(R.id.broken_image_photos);
broken_image_layout.addView(photo1);
broken_image_layout.addView(close_photo);
photo1.setOnClickListener(this);
close_photo.setOnClickListener(this);
submit_report.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.broken_img1:
Intent broken_imag_1 = new
Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(broken_imag_1,CAMERA_REQUEST);
break;
case R.id.broken_img1_close:
broken_image_layout.removeView(photo1);
broken_image_layout.removeView(close_photo);
break;
case R.id.btn_submit_report:
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent
data) {
super.onActivityResult(requestCode,resultCode,data);
if(requestCode == CAMERA_REQUEST && resultCode == RESULT_OK){
Bitmap photo = (Bitmap)data.getExtras().get("data");
photo1.getImgPhoto().setImageBitmap(photo);
}
}
In Your xml
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/multipleimages"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
//add your imageview here programatically
</LinearLayout>
</HorizontalScrollView>
In Java code
LinearLayout ll = (LinearLayout) findViewById(R.id.multipleimages);
ImageView imageView1=//your image 1
ImageView imageView2=//your image 2
ll.addView(imageView1);
ll.addView(imageView2);

Implementing a Gallery within an Android app

I am currently working on a small app and have the intention of building a gallery within the app. I currently have the camera intent working but I am not sure how to display the stored images in a grid (i.e. GridView). Here is the GalleryActivity:
public class GalleryActivity extends Activity {
TextView header;
private static final int ACT_START_CAMERA_APP = 0; //indicator to start the camera app
private ImageView capturedPhoto;
private String imageFileLocation = " ";
protected void onCreate(Bundle saveInstanceState){
super.onCreate(saveInstanceState);
setContentView(R.layout.gallery_activity);
capturedPhoto = (ImageView) findViewById(R.id.viewCapturedPhoto);
header = (TextView) findViewById(R.id.heading);
header.setTextKeepState("My Gallery");
}
#Override
public boolean onCreateOptionsMenu(Menu menu){
//inflate the menu; adds items to the action bar if present
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
//handles action bar item click here. The action bar
//will automatically handle clicks on the home button
//as long as you specify a parent activity in AndroidManifest.xml
#Override
public boolean onOptionsItemSelected(MenuItem item){
int id = item.getItemId();
if (id == R.id.action_settings){
return true;
}
return super.onOptionsItemSelected(item);
}
//invoked ACTION_IMAGE_CAPTURE - native Android method to access the camera
public void TakePhoto(View view){
Intent callCameraApplicationIntent = new Intent();
callCameraApplicationIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
File photoFile = null;
try{
photoFile = createImageFile(); //will contain the address of the captured photo
} catch (IOException exception) {
exception.getStackTrace();
}
//intent used to store the requested image/file i.e. photoFile
//tells Android where to store the picture
callCameraApplicationIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(callCameraApplicationIntent, ACT_START_CAMERA_APP);
}
//if we successfully take a picture print "Picture saved"
//else return "Cannot connect to camera" by default
protected void onActivityResult (int requestCode, int resultCode, Intent data){
//check if you have similar results for defining ACT_START_CAMERA_APP and resultCode
//if so, continue
if(requestCode == ACT_START_CAMERA_APP && resultCode == RESULT_OK) {
Toast.makeText(this, "Picture saved", Toast.LENGTH_SHORT).show();
Bitmap capturedPhotoBitmap = BitmapFactory.decodeFile(imageFileLocation);
capturedPhoto.setImageBitmap(capturedPhotoBitmap);
}
}
//allows storage of pictures on the phone
//create non-collision fileNames i.e. that do not have the same name and appends a stamp
//to the photo to make it unique
File createImageFile() throws IOException {
//create timestamp
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
//append timestamp to generic name IMAGE_
String imageFileName = "IMAGE_" + timeStamp + "_";
File storageDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
//now create the file
File image = File.createTempFile(imageFileName, ".jpg", storageDirectory);
imageFileLocation = image.getAbsolutePath();
return image;
}
I am wondering if storing the images that are returned by createImageFile() in a list and displaying the items from the list in a gridView fashion is feasible. Here is the .xml for the Gallery:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/heading"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="My Gallery"
android:textSize="30dp"
android:gravity="center"
android:textStyle="bold"
android:clickable="true"
android:background="#android:color/holo_blue_light"
android:textColor="#FFFFFF"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Camera"
android:id="#+id/photoButton"
android:onClick="TakePhoto"
android:clickable="true"
android:enabled="true"
android:layout_alignBottom="#+id/heading"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/photoButton"
android:id="#+id/viewCapturedPhoto"
android:clickable="true"
/>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="auto_fit"
android:columnWidth="90dp"
android:horizontalSpacing="10dp"
android:verticalSpacing="10dp"
android:gravity="center"
android:stretchMode="columnWidth"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/heading">
</GridView>
</RelativeLayout>
As you can see in the xml, I have the button for the camera and the GridView in the same file. Would it be better to have them separated? and finally, any implementation suggestions for my intentions (i.e. taking a photo, storing it, then displaying it in the grid)?

Camera opens on clicking anywhere rather than on button

Image for button 500x500.
I have created an ImageButton and when ImageButton is clicked the system camera should launch and the image brought from the system's camera app will be shown in the ImageView. But, the problem is: the button doesn't work here. Other than button if I click anywhere in the app the system camera launches but in case of button click the camera doesn't launch. What kind of error is causing this unexpected behaviour?
Java File:
public class Home extends AppCompatActivity {
static final int REQUEST_IMAGE_CAPTURE = 1;
ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// CAMERA BUTTON IMPLEMENTATION
ImageButton cameraButton = (ImageButton)findViewById(R.id.imageButton);
imageView = (ImageView)findViewById(R.id.imageView);
/* Disable the button if the user doesn't have camera */
if(!hasCamera())
cameraButton.setEnabled(false);
// CAMERA BUTTON IMPLEMENTATION
}
// Check if the user has a camera
private boolean hasCamera(){
return getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
}
// Launching the camera
public void launchCamera(View view){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//Take a picture and pass results along to onActivityResult
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
// If you want to return the image taken
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK){
//Get the photo
Bundle extras = data.getExtras();
Bitmap photo = (Bitmap) extras.get("data");
imageView.setImageBitmap(photo);
}
}
}
XML FILE:
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.muchmore.www.chasquido.Home"
android:background="#drawable/home_background"
android:id="#+id/home_activity"
android:onClick="launchCamera">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Welcome User!!!"
android:id="#+id/welcome_tag"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textColor="#000"
/>
<ImageButton
android:layout_width="90dp"
android:layout_height="90dp"
android:id="#+id/imageButton"
android:background="#drawable/camera_button"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView"
android:minHeight="300dp"
android:minWidth="300dp"
android:layout_above="#+id/imageButton"
android:layout_centerHorizontal="true" />
</RelativeLayout>
You have assigned OnClickListener android:onClick="launchCamera" to your RelativeLayout (your root view) instead to your ImageButton.

GPUImageToneCurveFilter returns black image after several camera capture

While the camera is live, I let the user choose any filter through a horizontal list just within the screen.
private void initializeVariables() {
mGPUImage = new GPUImage(this);
mGPUImage.setGLSurfaceView(glSurfaceView);
mCameraLoader = new CameraLoader(this, mGPUImage);
GPUImageFilterTools.showFilters(this, new GPUImageFilterTools.OnGpuImageFilterChosenListener() {
#Override
public void onGpuImageFilterChosenListener(GPUImageFilter filter) {
if (mFilter == null || (filter != null)) {
mFilter = filter;
mGPUImage.setFilter(mFilter);
}
}
}, hsv_camera_filters);
}
This is my initial setup, hsv_camera_filters is an instance of org.lucasr.twowayview.TwoWayView that lets the choices be displayed.
This is how I call curve files when user choose a filter
private static GPUImageFilter createFilterForType(final Context context, final FilterType type) {
GPUImageToneCurveFilter toneCurveFilter = null;
switch (type) {
case NONE:
return new GPUImageFilter();
case CONTRAST:
return new GPUImageContrastFilter(1.5f);
case CROSSPROCESS:
toneCurveFilter = new GPUImageToneCurveFilter();
toneCurveFilter.setFromCurveFileInputStream(context.getResources().openRawResource(
R.raw.crossprocess));
return toneCurveFilter;
case TWO:
toneCurveFilter = new GPUImageToneCurveFilter();
toneCurveFilter.setFromCurveFileInputStream(context.getResources().openRawResource(
R.raw.two));
return toneCurveFilter;
default:
throw new IllegalStateException("No filter of that type!");
}
}
The xml for this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#34393c"
android:orientation="vertical">
<android.opengl.GLSurfaceView
android:id="#+id/camera"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="20dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="100">
<RelativeLayout
android:id="#+id/camera_top_height"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="46"
android:background="#34393c"
android:gravity="center">
</RelativeLayout>
<LinearLayout
android:id="#+id/camera_preview_size"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="22"
android:orientation="vertical"></LinearLayout>
<LinearLayout
android:id="#+id/camera_bot_height"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:layout_weight="32"
android:background="#34393c"
android:gravity="center"
android:orientation="vertical"
android:weightSum="100">
<org.lucasr.twowayview.TwoWayView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/hsv_gallery_filters"
style="#style/TwoWayView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="45"
android:drawSelectorOnTop="true"
tools:context=".ActivityCamera" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="55"
android:gravity="center">
<Button
android:id="#+id/camera_img_capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onCapture"
android:text="capture"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
I initiate my camera capture like this:
#OnClick(R.id.camera_img_capture)
public void onCapture() {
mCameraLoader.getCamera().autoFocus(new Camera.AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
takePicture();
}
});
}
private void takePicture() {
Camera.Parameters paramss = mCameraLoader.getCamera().getParameters();
List<Camera.Size> pictureSizes = paramss.getSupportedPictureSizes();
/**
* Note : do not allow flash mode when using front-camera. Flash mode is
* off by default..Change default to auto
*/
if (mCameraLoader.getCameraId() == 0) {
switch (flashMode) {
case 1:// 0 = no flash, 1 = auto flash, 2 = flash on
paramss.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
break;
case 2:
paramss.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
break;
default:
paramss.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
break;
}
}
for (int i = 0; i < pictureSizes.size(); i++) {
if ((pictureSizes.get(i).height <= DEF_HEIGHT)
&& (pictureSizes.get(i).width <= DEF_WIDTH)) {
mCameraSize = pictureSizes.get(i);
paramss.setPictureSize(mCameraSize.width, mCameraSize.height);
paramss.setPreviewSize(mCameraSize.width, mCameraSize.height);
break;
}
}
mCameraLoader.getCamera().setParameters(paramss);
mCameraLoader.getCamera().takePicture(null, null, new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, final Camera camera) {
mCameraLoader.onPause();
final File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null) {
Log.d(TAG, "Error creating media file, check storage permissions");
return;
}
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
/**
* Note : detects camera angle and rearranges bytes to a desired
* angle
*/
Matrix matrix = new Matrix();
if (mCameraLoader.getCameraId() == 0) {
if (mOrientationRounded == 2) {
matrix.postRotate(90);
} else if (mOrientationRounded == 4) {
matrix.postRotate(-90);
}
} else {
if (mOrientationRounded == 2) {
matrix.postRotate(-90);
} else if (mOrientationRounded == 4) {
matrix.postRotate(90);
}
}
// Saves the image to the phone
saveImage(mGPUImage.getBitmapWithFilterApplied(bitmap));
}
});
}
And so the problem occurs in a ratio of 1:10 or 1:12 image captures with the filter, after that it only took 1:4, 1:3 or 1:2 image captures then the problem happens. It's like a pattern somehow but significantly it's not that accurate. I only tried this experiment with only one curve file.
How do I get this to work?
Is this a miscalculation of the library?
or is it just a variable manipulation error? or perhaps the setup?
Also got problem with black images. My code:
GPUImage gpuImage = new GPUImage(context);
gpuImage.setImage(sourceBitmap);
gpuImage.setFilter(filter);
Bitmap bitmap = gpuImage.getBitmapWithFilterApplied();
In my case putting this code into synchronized method solved the problem. Looks like getBitmapWithFilterApplied is not thread safe or there are some race condition in library.

Categories

Resources