Android taking a screenshot with MediaProjectionManager, OnImageAvailable doesn't start - java

I'm working on a android project, where there is an overlay button that is on top of other apps as well and when this button is clicked a screenshot should be taken. The overlay button works, but the screenshot part doesn't. I don't know why but it seems that the OnImageAvailable isn't starting. Here is a seperate project where I only test the screenshot part:
public class MainActivity extends Activity {
private static final int REQUEST_CODE= 100;
private MediaProjectionManager mProjectionManager;
private MediaProjection mProjection;
private ImageReader mImageReader;
private Handler mHandler = new Handler(Looper.getMainLooper());
private ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// call for the projection manager
mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
imageView = (ImageView) findViewById(R.id.imageView);
// start projection
final Button startButton = (Button)findViewById(R.id.button);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startProjection();
}
});
// start capture handling thread
new Thread() {
#Override
public void run() {
Looper.prepare();
mHandler = new Handler();
Looper.loop();
}
}.start();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
mProjection = mProjectionManager.getMediaProjection(resultCode, data);
if (mProjection != null) {
final DisplayMetrics metrics = getResources().getDisplayMetrics();
final int density = metrics.densityDpi;
final int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
final Display display = getWindowManager().getDefaultDisplay();
final Point size = new Point();
display.getSize(size);
final int width = size.x;
final int height = size.y;
mImageReader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 2);
mProjection.createVirtualDisplay("screencap", width, height, density, flags, mImageReader.getSurface(), null, mHandler);
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
Bitmap bitmap = null;
try {
image = mImageReader.acquireLatestImage();
if (image != null) {
final Image.Plane[] planes = image.getPlanes();
int width = image.getWidth();
int height = image.getHeight();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * width;
byte[] newData = new byte[width*height*4];
int offset = 0;
bitmap = Bitmap.createBitmap(metrics, width, height, Bitmap.Config.ARGB_8888);
ByteBuffer buffer = planes[0].getBuffer();
for(int i = 0; i < height; ++i){
for(int j = 0; j < width; ++j){
int pixel = 0;
pixel |= (buffer.get(offset) & 0xff) << 16; // R
pixel |= (buffer.get(offset + 1) & 0xff) << 8; // G
pixel |= (buffer.get(offset + 2) & 0xff); // B
pixel |= (buffer.get(offset + 3) & 0xff) << 24; // A
bitmap.setPixel(j, i, pixel);
offset += pixelStride;
}
offset += rowPadding;
}
imageView.setImageBitmap(bitmap);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bitmap!=null)
bitmap.recycle();
if (image!=null)
image.close();
}
}
}, mHandler);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void startProjection() {
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
}
}

I think you should set a different FLAGS.
You're telling the MediaProjection to display ITS OWN CONTENT ONLY but you're not drawing nothing on its surface.
To do a screenshot you have to REPLICATE A DIFFERENT DISPLAY using "DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR" flag.

Related

How to fix degree of image rotation after take image from front camera and back camera in android?

after take image from camera this image rotate with tow different degree between front camera and back camera I tried add rotation to image after take image from camera but it doesn't work with all devices by the same degree .
Note : I added face recognition but it doesn't work when images rotate,this is my code .
public class CheckIn extends AppCompatActivity {
private ImageView camera;
String encoded = "";
byte[] byteArray;
static final int REQUEST_IMAGE_CAPTURE = 1;
private Button checkIn;
ContentValues values;
public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 123;
Uri imageUri;
Bitmap thumbnail;
SparseArray<Face> faces ;
Matrix matrix ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_check_in);
camera = (ImageView) findViewById(R.id.camera);
checkIn = (Button) findViewById(R.id.submit);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "New Picture");
values.put(MediaStore.Images.Media.DESCRIPTION, "From your Camera");
imageUri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
});
checkPermissionREAD_EXTERNAL_STORAGE(this);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
try {
thumbnail = MediaStore.Images.Media.getBitmap(
getContentResolver(), imageUri);
if(Build.VERSION.SDK_INT >= 27) {
//only api 27 above
matrix = new Matrix();
matrix.postRotate(90);
}else{
//only api 27 down
matrix = new Matrix();
matrix.postRotate(270);
}
Bitmap rotatedBitmap = Bitmap.createBitmap(thumbnail, 0, 0, thumbnail.getWidth(), thumbnail.getHeight(), matrix, true);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Bitmap converetdImage = getResizedBitmap(rotatedBitmap, 700);
converetdImage.compress(Bitmap.CompressFormat.PNG, 10, byteArrayOutputStream);
byteArray = byteArrayOutputStream.toByteArray();
encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
RequestOptions options = new RequestOptions()
.centerCrop()
.placeholder(R.mipmap.ic_launcher_round)
.error(R.mipmap.ic_launcher_round);
Paint myRectPaint = new Paint();
myRectPaint.setStrokeWidth(5);
myRectPaint.setColor(Color.RED);
myRectPaint.setStyle(Paint.Style.STROKE);
Bitmap tempBitmap = Bitmap.createBitmap(rotatedBitmap.getWidth(), rotatedBitmap.getHeight(),
Bitmap.Config.RGB_565);
Canvas tempCanvas = new Canvas(tempBitmap);
tempCanvas.drawBitmap(rotatedBitmap, 0, 0, null);
FaceDetector faceDetector
= new
FaceDetector.Builder(getApplicationContext()).setTrackingEnabled(false)
.build();
Frame frame = new Frame.Builder().setBitmap(rotatedBitmap).build();
faces = faceDetector.detect(frame);
for (int i = 0; i < faces.size(); i++) {
Face thisFace = faces.valueAt(i);
float x1 = thisFace.getPosition().x;
float y1 = thisFace.getPosition().y;
float x2 = x1 + thisFace.getWidth();
float y2 = y1 + thisFace.getHeight();
tempCanvas.drawRoundRect(new RectF(x1, y1, x2, y2), 2, 2, myRectPaint);
}
Glide.with(CheckIn.this).load(tempBitmap).apply(options)
.into(camera);
} catch (Exception e) {
e.printStackTrace();
} }
}
public void checkPermissionREAD_EXTERNAL_STORAGE(
final Context context) {
// Enable if permission granted
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_GRANTED) {
}
// Else ask for permission
else {
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
}
public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
int width = image.getWidth();
int height = image.getHeight();
float bitmapRatio = (float) width / (float) height;
if (bitmapRatio > 1) {
width = maxSize;
height = (int) (width / bitmapRatio);
} else {
height = maxSize;
width = (int) (height * bitmapRatio);
}
return Bitmap.createScaledBitmap(image, width, height, true);
}
}
thanks in advance .
try this please
i just have to add
camera.setDisplayOrientation(90);
now the display is on the right angle.

Trouble getting order of Image Bitmap layers in Android correct

I have a piece of code that compares to images and places a marker on the difference. So far it works well, except the latest marker layer that is added always shows underneath all the older markers. I have the latest one as a yellow color and the older ones as red. When the difference is close to one of the red markers, the yellow marker shows behind those ones.
Is there anyone that can help me get the yellow (Latest marker) to appear on top?
This is my code so far:
public class CheckmarkActivity extends AppCompatActivity implements ZoomLayout.OnZoomableLayoutClickEventListener {
TextView tv;
RelativeLayout relativeLayout_work;
ImageView imageViewtest;
Bitmap prevBmp = null;
Timer t;
TimerTask task;
int time = 100;
float image_Width;
float image_Height;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_checkmark);
if (getResources().getBoolean(R.bool.is_tablet)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
tv = findViewById(R.id.tv);
relativeLayout_work = findViewById(R.id.relativeLayout_work);
imageViewtest = findViewById(R.id.imageViewtest);
prevBmp = ViewcontrollerActivity.workSession.getLastScreenShot();
if (prevBmp == null || ViewcontrollerActivity.workSession.workScreenShot == null) {
setResult(Activity.RESULT_CANCELED);
finish();
}
startTimer();
}
// image compare
class TestAsync extends AsyncTask<Object, Integer, String>
{
String TAG = getClass().getSimpleName();
PointF p;
Bitmap test_3;
protected void onPreExecute (){
super.onPreExecute();
Log.d(TAG + " PreExceute","On pre Exceute......");
}
protected String doInBackground(Object...arg0) {
test_3 = ImageHelper.findDifference(CheckmarkActivity.this, prevBmp, ViewcontrollerActivity.workSession.workScreenShot);
p = ImageHelper.findShot(test_3);
time = 1;
return "You are at PostExecute";
}
protected void onProgressUpdate(Integer...a){
super.onProgressUpdate(a);
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
addImageToImageview();
PointF np = Session.convertPointBitmap2View(p, relativeLayout_work, ViewcontrollerActivity.workSession.workScreenShot);
tv.setX(np.x - tv.getWidth() / 2);
tv.setY(np.y - tv.getHeight() / 2);
tv.setVisibility(View.VISIBLE);
// imageViewtest.setImageBitmap(test_3);
}
}
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i("OpenCV", "OpenCV loaded successfully");
new TestAsync().execute();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
#Override
protected void onResume() {
super.onResume();
if (!OpenCVLoader.initDebug()) {
Log.d("OpenCV", "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
} else {
Log.d("OpenCV", "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
public static int[] getBitmapOffset(ImageView img, Boolean includeLayout) {
int[] offset = new int[2];
float[] values = new float[9];
Matrix m = img.getImageMatrix();
m.getValues(values);
offset[0] = (int) values[5];
offset[1] = (int) values[2];
if (includeLayout) {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) img.getLayoutParams();
int paddingTop = (int) (img.getPaddingTop() );
int paddingLeft = (int) (img.getPaddingLeft() );
offset[0] += paddingTop + lp.topMargin;
offset[1] += paddingLeft + lp.leftMargin;
}
return offset;
}
public static int[] getBitmapPositionInsideImageView(ImageView imageView) {
int[] ret = new int[4];
if (imageView == null || imageView.getDrawable() == null)
return ret;
// Get image dimensions
// Get image matrix values and place them in an array
float[] f = new float[9];
imageView.getImageMatrix().getValues(f);
// Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
final float scaleX = f[Matrix.MSCALE_X];
final float scaleY = f[Matrix.MSCALE_Y];
// Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
final Drawable d = imageView.getDrawable();
final int origW = d.getIntrinsicWidth();
final int origH = d.getIntrinsicHeight();
// Calculate the actual dimensions
final int actW = Math.round(origW * scaleX);
final int actH = Math.round(origH * scaleY);
ret[2] = actW;
ret[3] = actH;
// Get image position
// We assume that the image is centered into ImageView
int imgViewW = imageView.getWidth();
int imgViewH = imageView.getHeight();
int top = (int) (imgViewH - actH)/2;
int left = (int) (imgViewW - actW)/2;
ret[0] = left;
ret[1] = top;
return ret;
}
private void addImageToImageview(){
if (ViewcontrollerActivity.workSession.workScreenShot != null) {
imageViewtest.setImageBitmap(ViewcontrollerActivity.workSession.workScreenShot);
Log.d("width", String.valueOf(imageViewtest.getWidth()));
}
Resources r = getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());
for (int i = 0; i < ViewcontrollerActivity.workSession.getShotCount(); i++) {
PointF p = ViewcontrollerActivity.workSession.getPoint(i);
TextView t = new TextView(this);
t.setText("" + (i + 1));
RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams((int)px, (int)px);
relativeLayout_work.addView(t);
t.setLayoutParams(param);
t.setGravity(Gravity.CENTER);
t.setBackgroundResource(R.drawable.circle);
p = Session.convertPointBitmap2View(p, relativeLayout_work, ViewcontrollerActivity.workSession.workScreenShot);
t.setX(p.x);
t.setY(p.y);
t.setTag(10000 + i);
}
}
public void onConfirm(View v){
View vv = findViewById(R.id.relativeLayout_work);
PointF bp = Session.convertPointView2Bitmap(new PointF(tv.getX(), tv.getY()), relativeLayout_work, ViewcontrollerActivity.workSession.workScreenShot);
ViewcontrollerActivity.workSession.addNewShot(ViewcontrollerActivity.workSession.workScreenShot, bp);
setResult(Activity.RESULT_OK);
finish();
}
public void onCancel(View v){
setResult(Activity.RESULT_CANCELED);
finish();
}
#Override
public void onBackPressed() {
setResult(Activity.RESULT_CANCELED);
finish();
}
#Override
public void OnContentClickEvent(int action, float xR, float yR) {
int[] offset = new int[2];
int[] rect = new int[4];
offset = this.getBitmapOffset(imageViewtest, false);
int original_width = imageViewtest.getDrawable().getIntrinsicWidth();
int original_height = imageViewtest.getDrawable().getIntrinsicHeight();
rect = getBitmapPositionInsideImageView(imageViewtest);
Log.i("OffsetY", String.valueOf(offset[0]));
Log.i("OffsetX", String.valueOf(offset[1]));
Log.i( "0", String.valueOf(rect[0]));
Log.i( "1", String.valueOf(rect[1]));
Log.i( "2", String.valueOf(rect[2]));
Log.i( "3", String.valueOf(rect[3]));
if (xR > rect[0] && xR < rect[0] + rect[2] && yR > rect[1] && yR < rect[1] + rect[3]) {
tv.setX(xR - tv.getWidth() / 2);
tv.setY(yR - tv.getHeight() / 2);
}
// tv.setX(xR - tv.getWidth() / 2);
// tv.setY(yR - tv.getHeight() / 2);
}
public void onMoveButtonPressed(View v) {
ImageButton b = (ImageButton)v;
int mId = b.getId();
switch (mId) {
case R.id.imageButtonL:
tv.setX(tv.getX() - 1);
break;
case R.id.imageButtonR:
tv.setX(tv.getX() + 1);
break;
case R.id.imageButtonD:
tv.setY(tv.getY() + 1);
break;
case R.id.imageButtonU:
tv.setY(tv.getY() - 1);
break;
}
}
//timer change image
public void startTimer(){
t = new Timer();
task = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (time == 1){
imageViewtest.setImageBitmap(ViewcontrollerActivity.workSession.workScreenShot);
// tv.setVisibility(View.VISIBLE);
tv.setText("" + (ViewcontrollerActivity.workSession.getShotCount() + 1));
t.cancel();
return;
}
if (time % 2 == 0) {
imageViewtest.setImageBitmap(prevBmp);
}
else if(time % 2 == 1){
imageViewtest.setImageBitmap(ViewcontrollerActivity.workSession.workScreenShot);
}
time --;
}
});
}
};
t.scheduleAtFixedRate(task, 0, 500);
}
}
You can give the z-order of the child view with addView() function.
void addView (View child, int index)
ex)
private void addImageToImageview(){
if (ViewcontrollerActivity.workSession.workScreenShot != null) {
imageViewtest.setImageBitmap(ViewcontrollerActivity.workSession.workScreenShot);
Log.d("width", String.valueOf(imageViewtest.getWidth()));
}
Resources r = getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());
int currChildrenCount = relativeLayout_work.getChildCount();
for (int i = 0; i < ViewcontrollerActivity.workSession.getShotCount(); i++) {
PointF p = ViewcontrollerActivity.workSession.getPoint(i);
TextView t = new TextView(this);
t.setText("" + (i + 1));
RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams((int)px, (int)px);
relativeLayout_work.addView(t, currChildrenCount+i); // You can control the order like this
t.setLayoutParams(param);
t.setGravity(Gravity.CENTER);
t.setBackgroundResource(R.drawable.circle);
p = Session.convertPointBitmap2View(p, relativeLayout_work, ViewcontrollerActivity.workSession.workScreenShot);
t.setX(p.x);
t.setY(p.y);
t.setTag(10000 + i);
}
}

Create a new bitmap with double the number of pixels in a previously stored bitmap

First of all, I am picking an image from the gallery and converting it into bitmap.
What i want to achieve is that, when a certain button is pressed, a new bitmap is created with double the number of pixels in the previously stored bitmap. Next, each pixel from the original bitmap should be stored in four pixels around the same co ordinates in the new bitmap.
I have tried looping through both of the bitmaps but I'm getting an error which says Y SHOULD BE > BITMAP.HEIGHT()
not sure what I'm getting wrong here.
And even if i fix this error in the loop, can the UI thread even manage to loop through a large number of pixels without becoming unresponsive?
The MainActivity code is pasted below:
public class MainActivity extends AppCompatActivity {
static final int PICK_IMAGE = 11;
ImageView image;
Bitmap bmp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button chooseImage = (Button) findViewById(R.id.choose_btn);
Button apply = (Button) findViewById(R.id.apply_btn);
image = (ImageView) findViewById(R.id.image_view);
chooseImage.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);
}
});
apply.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int viewHeight = image.getHeight();
int viewWidth = image.getWidth();
int bmpHeight = bmp.getHeight();
int bmpWidth = bmp.getWidth();
Bitmap betterQuality = Bitmap.createBitmap(bmpWidth*2, bmpHeight*2, Bitmap.Config.ARGB_8888);
int newXVal = 0, newYVal = 0, limX = 2, limY = 2;
int color;
for (int x = 0; x < bmpWidth; x++) {
for (int y = 0; y < bmpHeight; y++) {
for (int a = newXVal; a < limX; a++) {
for (int b = newYVal; b < limY; b++) {
color = bmp.getPixel(x, y);
betterQuality.setPixel(a, b, Color.argb(Color.alpha(color), Color.red(color), Color.blue(color), Color.green(color)));
}
}
newXVal++;
newYVal++;
limX++;
limY++;
}
}
image.setImageBitmap(betterQuality);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE && resultCode == RESULT_OK){
Uri selectedImage = data.getData();
try {
bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage));
image.setImageBitmap(bmp);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
}

setpixel in bitmap android

I have a bitmap that I want to set a new pixel value for every pixel at bitmap.
Here is my code :
Bitmap bm=((BitmapDrawable)imageView.getDrawable()).getBitmap();
int W = bm.getWidth();
int H = bm.getHeight();
int [][][] clr = new int [3][H][W];
int pixel;
for(int i=0;i<W;i++)
for(int j=0;j<H;j++){
pixel = bm.getPixel(i, j);
clr[0][j][i] = Color.red(pixel);
clr[1][j][i] = Color.green(pixel);
clr[2][j][i] = Color.blue(pixel);
}
/*
...
pixel changging process
...
*/
//save a new image
for(int i=0;i<W;i++)
for(int j=0;j<H;j++)
bm.setPixel(i, j, Color.rgb(clr[0][j][i],clr[1][j][i],clr[2][j][i]));
saveImageFile(bm);
//end save new image
what am I supposed to do? The save new image process couldn't work and I need an alternative to work on this issue
thanks in advance :)
This code is working !!
Set the new bitmap in ImageView and its working !
public class Bleach extends AppCompatActivity implements Cloneable {
Bitmap bm;
ImageButton bDone;
Bitmap _bitmapPrev;
Bitmap _bitmapCur;
File imageFile;
Bitmap bm3;
Bitmap bm4;
ImageView bl;
int x;
int y;
String[] projection = new String[]{
MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA,
MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
MediaStore.Images.ImageColumns.DATE_TAKEN,
MediaStore.Images.ImageColumns.MIME_TYPE
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bleach);
bDone = (ImageButton) findViewById(R.id.donebtnid);
bDone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
startActivity(new Intent(Bleach.this, MainMenuActivity.class));
}
});
//bl = (ImageView)findViewById(R.id.pickbleachi d);
final Cursor cursor = getContentResolver()
.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null,
null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC");
if (cursor != null) {
if (cursor.moveToFirst()) {
final ImageView bl = (ImageView) findViewById(R.id.pickbleachid);
String imageLocation = cursor.getString(1);
imageFile = new File(imageLocation);
if (imageFile.exists()) { // TODO: is there a better way to do this?
try{
bm = BitmapFactory.decodeFile(imageLocation);
bm3 = ExifUtil.rotateBitmap(imageLocation,bm);
}catch (Exception exception){
Log.d("PICtureConfirmation ","bm decodefile"+ exception.getMessage());
}
try {
// bl.setImageBitmap(bm3);
//Drawable imgDrawable = teeth.getDrawable();
//Bitmap bm5=((BitmapDrawable)bm3.getDrawable()).getBitmap();
int W = bm3.getWidth();
int H = bm3.getHeight();
int [][][] clr = new int [3][H][W];
int pixel;
for(int i=0;i<W;i++)
for(int j=0;j<H;j++){
pixel = bm3.getPixel(i, j);
clr[0][j][i] = Color.red(pixel+5);
clr[1][j][i] = Color.green(pixel+5);
clr[2][j][i] = Color.blue(pixel+5);
}
/*
...
pixel changging process
...
*/
//save a new image
for(int i=0;i<W;i++) {
for (int j = 0; j < H; j++) {
bm3.setPixel(i, j, Color.rgb(clr[0][j][i], clr[1][j][i], clr[2][j][i]));
}
}
bl.setImageBitmap(bm3);
}
catch (Exception e){}
}
}
}
}
public void SetGamma(double red,double green, double blue){
Bitmap temp = (Bitmap)_bitmapCur;
//Bitmap bmap = (Bitmap)temp.clone();
}
}

Why i capture more than one time but the app pick only first picture to process

I have two activity one is for take an image and another is process image. but i found the problem that when i take a photo for more than one time. The picture that is processed is still an the first one. why it not change picture. and how i can fix it.
this is a first activity for take an image
public class CaptureCamera extends Activity {
Camera mCamera = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.layout_start);
mCamera = getCameraInstance();
Preview mPreview = new Preview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.cam_preview);
preview.addView(mPreview);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int screenCenterX = (size.x /4);
int screenCenterY = (size.y/6) ;
//Adding listener
ImageView captureButton = (ImageView) findViewById(R.id.button_camera);
captureButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.takePicture(null, null, mPicture);
}
});
//Adding listener
ImageView backButton = (ImageView) findViewById(R.id.button_back);
backButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent1 = new Intent(CaptureCamera.this, MainMenuActivity.class);
finish();
startActivity(intent1);
}
});
//Adding listener
ImageView nextButton = (ImageView) findViewById(R.id.button_next);
nextButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent2 = new Intent(CaptureCamera.this, ProcessPic.class);
finish();
startActivity(intent2);
}
});
}
private Camera getCameraInstance() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
// cannot get camera or does not exist
}
return camera;
}
PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null){
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
Toast.makeText(CaptureCamera.this, "Photo saved to folder \"sdcard\\DCIM\\CameraSnap\"", Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
};
private static File getOutputMediaFile(){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM), "CameraSnap");
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("CameraSnap", "failed to create directory");
return null;
}
};
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator +"IMG_0"+".jpg");
return mediaFile;
}
}
class Preview extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
Camera mCamera;
Preview(Context context, Camera camera) {
super(context);
// Install a SurfaceHolder.Callback so we get notified when
this.mCamera = camera;
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
//this is a deprecated method, is not required after 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell
// to draw.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the
// Because the CameraDevice object is not a shared resource,
// important to release it when the activity is paused.
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters
// the preview.
Camera.Parameters parameters = mCamera.getParameters();
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
// You need to choose the most appropriate previewSize for your app
Camera.Size previewSize = previewSizes.get(0);
parameters.setPreviewSize(previewSize.width, previewSize.height);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
Here is Process Activity that will get image from DCIM/capturesnap and calculate HSV color
But when i have take second picture and then click button to this activity. the output (HSV color) that is shown is still belong to the old picture.
How i can fix it, in order to process picture in the last picture not the old one.
public class ProcessPic extends Activity {
public static ArrayList<Double> HueValue = new ArrayList<Double>(9);
public static int xImage,yImage,red,green,blue,RR,Y,B;
public static float[] hsv = new float[3];
public static Bitmap myBitmapPic,myBitmapPic1;
public static double a,b,r,std_err = 0.0;
public static double e;
public static int N;
//Variable for Vmode
public static int Rred,Ggreen,Bblue, maxCount;
static float maxValue;
public static float[] hsvMode = new float[3];
public static int[] ModeValue = new int[17415];//rare data
public static double[] HueValueMode = new double[17415];//rare data
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_process);
TextView tv1 = (TextView)findViewById(R.id.textView1);
String path = Environment.getExternalStorageDirectory()+
File imgFile = new File(path);
myBitmapPic1 = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
//resize
Bitmap myBitmapPic = null;
myBitmapPic = Bitmap.createScaledBitmap(myBitmapPic1, 2560, 1920, true);
ImageView myImage = (ImageView) findViewById(R.id.imageAdd);
myImage.setImageBitmap(myBitmapPic);
//0
ProcessPic h1ppm = new ProcessPic();
h1ppm.AverageColor(myBitmapPic, 244,395,1198,1388);
HueValue.add((double) hsv[0]);
ProcessPic model = new ProcessPic();
model.Regression(x, y);
tv1.setText(hsv[0]);
//Adding listener
ImageView backButton = (ImageView) findViewById(R.id.imageBack);
backButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(ProcessPic.this, MainMenuActivity.class);
finish();
startActivity(intent);
}
});
//Adding listener
ImageView nextButton = (ImageView) findViewById(R.id.imageSave);
nextButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent1 = new Intent(ProcessPic.this, AddStudent.class);
finish();
startActivity(intent1);
}
});
}
public static void AverageColor (Bitmap myBitmap,int minw, int maxw,int minh, int maxh){//for master color
red = 0;
green = 0;
blue = 0;
int count = 0;
for (int i=minw;i<maxw;i++){
for (int j=minh;j<maxh;j++){
int pixel = myBitmap.getPixel(i,j);
red += pixel >> 16 & 0xFF;
green += pixel >> 8 & 0xFF;
blue += pixel & 0xFF;
count++;
}
}
red /= count;
green /= count;
blue /= count;
//---------------------convert RGB to HSV----------------//
int avgRed = red;
int avgGreen = green;
int avgBlue = blue;
Color.RGBToHSV(avgRed,avgGreen,avgBlue,hsv);
//float hue = hsv[0];
//float saturate = hsv[1];
//float brightness = hsv[2];
}
public static void ValueArray (Bitmap myBitmap,int minw, int maxw,int minh, int maxh) {//for หลุม
Rred = 0;
Ggreen = 0;
Bblue = 0;
int count = 0;
for (int i=minw;i<maxw;i++){
for (int j=minh;j<maxh;j++){
int pixel = myBitmap.getPixel(i,j);
Rred = pixel >> 16 & 0xFF;
Ggreen = pixel >> 8 & 0xFF;
Bblue = pixel & 0xFF;
ProcessPic.RGBtoHSV(Rred, Ggreen, Bblue, hsvMode);
//Color.RGBToHSV(Rred,Ggreen,Bblue,hsvMode);
//create V array
//ModeValue[count] = (int)(hsvMode[2]*100);//ทำไมตรงนี้ค่ามันมากกว่า [0...1]
//HueValueMode[count] = hsvMode[0];
ModeValue[count] = (int)(hsvMode[2]*100);
HueValueMode[count] = hsvMode[0];
//can create h at this
count++;
}
}
}
public static int Mode(int a[]) {//ModeValue[]
for (int i = 0; i < a.length; ++i) {
int count = 0;
for (int j = 0; j < a.length; ++j) {
if (a[j] == a[i])
++count;
}
if (count > maxCount) {
maxCount = count;
maxValue = a[i];
}
}
return (int) maxValue;
}
public static double averagehuemode(int a[]) {//ModeValue[]
double temp=0;
int count=0;
for (int i = 0; i < a.length; ++i) {
if (a[i] >= maxValue-5 && a[i] <= maxValue+5){//เลขตรงนี้
temp+= HueValueMode[i];
count++;
}
}
return temp/count;
}
public static void RGBtoHSV(int r, int g, int b, float[] hsvMode){
double h, s, v;
double min, max, delta;
min = Math.min(Math.min(r, g), b);
max = Math.max(Math.max(r, g), b);
// V
v = max/255;
delta = max - min;
// S
if( max != 0 )
s = delta / max;
else {
s = 0;
h = -1;
//return new double[]{h,s,v};
}
// H
if( r == max )
h = ( g - b ) / delta; // between yellow & magenta
else if( g == max )
h = 2 + ( b - r ) / delta; // between cyan & yellow
else
h = 4 + ( r - g ) / delta; // between magenta & cyan
h *= 60; // degrees
if( h < 0 )
h += 360;
hsvMode[0] = (int)(h);
hsvMode[1] = (float)(s);
hsvMode[2] = (float)(v);
}
Few points to consider:
After calling Camera.takePicture(), preview stops, so "to take more photos, call startPreview() first" - do in after saving image in onPictureTaken(), eg:
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
Toast.makeText(CaptureCamera.this, "Photo saved to folder \"sdcard\\DCIM\\CameraSnap\"", Toast.LENGTH_SHORT).show();
//start preview to take more pictures
mCamera.startPreview();
Do not swallow exceptions - if something goes wrong, you won't know it. Add printStackTrace() in onPictureTaken():
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
Toast.makeText(CaptureCamera.this, "Photo saved to folder \"sdcard\\DCIM\\CameraSnap\"", Toast.LENGTH_SHORT).show();
//start preview to take more pictures
mCamera.startPreview();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
When calling other activities, instead of:
Intent intent1 = new Intent(CaptureCamera.this, MainMenuActivity.class);
finish();
startActivity(intent1);
call finish() last, so:
Intent intent1 = new Intent(CaptureCamera.this, MainMenuActivity.class);
startActivity(intent1);
finish();

Categories

Resources