How to get a camera preview's pixels in Android? - java

I want to know how to get an array of pixels from the preview webcam (which I will run in a service). I've heard that the preview has to be displayed on a surface, but there will be no surface if I use a service.
I am very new to Android development, sorry for any misconceptions.
Thanks.

Parameters parameters = camera.getParameters();
Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
if(display.getRotation() == Surface.ROTATION_0)
{
parameters.setPreviewSize(640, 480);
camera.setDisplayOrientation(90);
}
camera.setParameters(parameters);
camera.setPreviewDisplay(cameraSurfaceHolder);
camera.startPreview();
previewing = true;

Related

Camera Intent Image Preview Orientation

I take an image in Android using the following Code:
File image = new File(this.images_object_dir, loadedObjekt.getFilename());
Uri uri = FileProvider.getUriForFile(this, FILE_PROVIDER, image);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, CAMERA_ACTIVITY_CODE);
In the camera intent, the image preview is always in portrait mode on my Huawei P20 Pro. On another test-device the preview image (the one where you can decide if you wanna retake the image) is stuck in the "inital" rotation as well which looks ugly. For instance, if you want to take an image in landscape mode, the preview gets flipped to portrait mode.
Is there a solution for this?
There are ~2 billion Android devices, spread across ~20,000 device models. There are dozens, if not hundreds, of pre-installed camera apps across those device models. There are plenty of other camera apps that the user can download and install.
Your code might start any of them.
In the camera intent, the image preview is always in portrait mode on my Huawei P20 Pro
That is the behavior of that one camera app out of hundreds.
On another test-device the preview image (the one where you can decide if you wanna retake the image) is stuck in the "inital" rotation as well which looks ugly.
That is the behavior of that one camera app out of hundreds.
There is no requirement for a camera app to behave that way. Of course, there is no requirement for a camera app to have preview images at all.
Is there a solution for this?
If you wish to use ACTION_IMAGE_CAPTURE, no. The behavior of those hundreds of camera apps is up to the developers of those camera apps, not you.
There are other options for taking pictures, such as using the camera APIs directly or using third-party libraries like Fotoapparat or CameraKit-Android.
Use ExifInterface to check the orientation of the image while decoding it. Then you rotate the image to get required image in proper orientation.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
Bitmap decoded = BitmapFactory.decodeFile(filePath, options);
if (decoded == null) return null;
try {
ExifInterface exif = new ExifInterface(filePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotation = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
rotation = 90;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
rotation = 270;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
rotation = 180;
}
if (rotation != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
Bitmap newBitmap = Bitmap.createBitmap(decoded, 0, 0, decoded.getWidth(),
decoded.getHeight(), matrix, true);
decoded.recycle();
Runtime.getRuntime().gc();
decoded = newBitmap;
}
} catch (IOException e) {
e.printStackTrace();
}
If you want to use support library in order to support devices with lower API levels, use the following dependency:
implementation 'com.android.support:exifinterface:27.1.1'
and import android.support.media.ExifInterface

Image from ACTION_IMAGE_CAPTURE Rotated

I am trying to simply get an image from a phone's camera. Surprisingly, it returns rotated. I've scoured the internet for fixes and came across many solutions using ExifInterface, but it only works sometimes. It gets the orientation wrong seemingly randomly, as I merely recompile and see different results. I have found some people saying this is a fault of the class itself being bugged.
I found other solutions that require like two additional libraries and more java files to do the job, but that just seems ridiculous (and I am avoiding additional packages). How come images are rotated in the first place (in storage they are perfectly fine), and how hard can it possibly be to fix the issue? Also - rotating the Image View also works (and seems much easier than literally creating a rotated image), but I need to know by how much to rotate the view.
EDIT---- I realized that the image is consistently rotated 270 degrees clockwise from the orientation the image was taken in (inside the intent) if the back camera was used, and 90 degrees if the front camera was used. Thus I only really need a way to find out this orientation.
Intent called here:
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = setUpPhotoFile();
mCurrentPhotoPath = photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
} catch (IOException ex) {
// Error occurred while creating the File
photoFile = null;
mCurrentPhotoPath = null;
}
// Continue only if the File was successfully created
if (photoFile != null) {
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
} else {
Toast noStorage = Toast.makeText(this, "Cannot access mounted storage.", Toast.LENGTH_SHORT);
noStorage.show();
}
}
}
Bitmap created here:
private void setPic() {
/* Get the size of the ImageView */
int targetW = mImageView.getWidth();
int targetH = mImageView.getHeight();
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
/* Figure out which way needs to be reduced less */
int scale = 1;
if (photoH > targetH|| photoW > targetW) {
scale = Math.max(
(int)Math.pow(2, (int) Math.ceil(Math.log(targetW /
(double) photoW)) / Math.log(0.5)),
(int)Math.pow(2, (int) Math.ceil(Math.log(targetH /
(double) photoH)) / Math.log(0.5)));
;
}
/* Set bitmap options to scale the image decode target */
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scale;
/* Decode the JPEG file into a Bitmap */
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
/*-----------How should I rotate bitmap/mImageView to correct orientation?*/
/* Associate the Bitmap to the ImageView */
mImageView.setImageBitmap(bitmap);
mImageView.setVisibility(View.VISIBLE);
}
The best solution I have found is this one:
https://www.samieltamawy.com/how-to-fix-the-camera-intent-rotated-image-in-android/
I post the link because I don't want all the credit.
Sami Eltamawy has written a function that rotate the image if its need to be rotated.
I try the code and is working on my devices that the image got rotated.

Wallpaper issue, picture is zoomed in when i press set background

I am making a wallpaper application, i have one issue:
when i try to click my button "Set background", it sets the background but it is zoomed in and because of that i lost half of my original image. This is the code that i am using:
try {
Display d = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = d.getWidth();
int height = d.getHeight();
WallpaperManager wallpaperManager = WallpaperManager.getInstance(view.getContext());
Bitmap bitmap = null;
bitmap = Bitmap.createScaledBitmap(bmpWallpaper, width, height, false);
wallpaperManager.setBitmap(bitmap);
Core.makeNotification(view.getContext(), "MyNotification", "Your wallpaper has been set, enjoy!");
Core.makeAlert(view.getContext(), "Wallpaper set", "Your wallpaper has been set, enjoy!");
} catch (IOException e) {
e.printStackTrace();
}
i had the same problem and fix it by multiplying the size by 2 for each photo
for example 2160*1920 instead of 1080*960 for all variations specially Galaxy S4
by multiplying the size by 2 i mean by that; the image it self not doing it programmatically

JavaCV Grabber webcam only working on my computer?

So I created an executable JAR using this code and everything works fine on my machine however I tested it on some other computers and the webcam capture never starts. The indicator light doesn't come on. This is the example I see in most tutorials for doing image capture and I'm doing face recognition so it's easiest to utilize the javaCV function rather than adding another library. All suggestions appreciated, thank you.
CanvasFrame canvas = new CanvasFrame("Webcam");
//Set Canvas frame to close on exit
canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
try {
//Start grabber to capture video
grabber.start();
//Declare img as IplImage
IplImage img;
long starttime = System.currentTimeMillis();
while (temptime < 4000) {
//inser grabed video fram to IplImage img
img = grabber.grab();
//Set canvas size as per dimentions of video frame.
canvas.setCanvasSize(grabber.getImageWidth(), grabber.getImageHeight());
if (img != null) {
//Flip image horizontally
cvFlip(img, img, 1);
//Draw text over the canvas
Graphics g = canvas.createGraphics();
g.setFont(camfont);
g.setColor(Color.red);
//Show video frame in canvas
canvas.showImage(img);
if (temptime > 2000 && tempcount == 1) {
//take and save the picture
cvSaveImage("User-cap.jpg", img);
tempcount++;
}
temptime = System.currentTimeMillis() - starttime;
}
}
} catch (Exception e) {
}
try {
grabber.stop();
canvas.dispose();
} catch (Exception e) {
System.out.println("Grabber couldn't close.");
}
you need to have OpenCV installed in the machine where you are running that program , jar only will contain javacv wrapper , but doesnt contains dll of opencv

camera preview gives gray images

i am developing android app using android sdk camera. on camera preview i need the frame content so i am using PreviewCallback to return the data in byte array, now my problem is saving the data in mat object the mat return gray images:
public void onPreviewFrame(byte[] data, Camera camera) {
Mat src = new Mat(previewSize.height, previewSize.width, CvType.CV_8U, new Scalar(255));
src.put(0, 0, data);
Highgui.imwrite("/mnt/sdcard/1.jpg", src);
}
anybody can help me to generate argb images
note: i am using NV21 in preview image format.
Do this instead:
Mat src = new Mat(previewSize.height, previewSize.width, CvType.CV_8UC3);
If it does not work, it means your data is already gray, so you must have set it as gray somewhere in your code.

Categories

Resources