I've created an camera application which has an image on camera preview. This is image is a hat, for example, and I want to take an photo of an person with the hat image over his head. This is what I've done:
mFrameLayout = new FrameLayout(this);
mPreview = new Preview(this);
mFrameLayout.addView(mPreview);
mImage = new ImageView(this);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(100, 100);
layoutParams.leftMargin = 200;
layoutParams.topMargin = 100;
mImage.setLayoutParams(layoutParams);
mImage.setImageResource(R.drawable.gorro);
mFrameLayout.addView(mImage);
mFrameLayout.setOnClickListener(this);
setContentView(mFrameLayout);
Preview Class:
class Preview extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "Preview";
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;
Preview(Context context) {
super(context);
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView);
}
And this class has all the surface methods implemented.
When I touch on any place on the Camera, the photo is taken. Here's the code:
public void onClick(View arg0) {
Toast.makeText(this, "Taken!", Toast.LENGTH_LONG).show();
mCamera.takePicture(null, mPictureCallback, mPictureCallback);
}
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] imageData, Camera c) {
if (imageData != null) {
String root = Environment.getExternalStorageDirectory()
.toString();
File myDir = new File(root + "/saved_images2");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
out.write(imageData);
out.flush();
out.close();
Log.d("teste", "onPictureTaken - wrote bytes: "
+ imageData.length);
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
The problem is when I take an photo with the .png image, the photo is saved without it.
How can I also save the .png image when photo is taken ?
You have to convert your imageData to Bitmap in PictureCallBack and then use a Canvas with method drawBitmap to draw your hat bitmap onto the captured image from Camera. Finally you can save result bitmap to a file.
So:
Bitmap cameraBitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
Canvas canv = new Canvas(cameraBitmap );
canv.drawBitmap(.... your hat image);
Related
I'm building an android tesseract app. It was reading the data fine until I was taking photos from the default camera app. Now, I needed to implement my own custom camera, that caused it to start giving wrong result.
public class getButtonClicked implements View.OnClickListener{
public void onClick(View arg0) {
DATA_PATH = Environment.getExternalStorageDirectory().toString() + "/MyOCRApp/";
File tessdata = new File(DATA_PATH);
if (!tessdata.isDirectory()){
throw new IllegalArgumentException("Data path must contain subfolder tessdata!");
}
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.setDebug(true);
baseApi.init(DATA_PATH, lang);
if (newImg == null){
baseApi.setImage(imageBitmap);
}
else{
baseApi.setImage(newImg);
}
String recognizedText = baseApi.getUTF8Text();
// 1. Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(context);
// 2. Chain together various setter methods to set the dialog characteristics
builder.setMessage("Recognized Text:\n\n" + recognizedText);
// 3. Get the AlertDialog from create()
AlertDialog dialog = builder.create();
dialog.show();
//baseApi.end();
}
}
This is the code that calls the tesseract APIs.
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d("Error creating file" ,"!");
return;
}
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int screenHeight = getResources().getDisplayMetrics().heightPixels;
bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// Notice that width and height are reversed
Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true);
int w = scaled.getWidth();
int h = scaled.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
MainActivity.imageBitmap = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true);
}else{// LANDSCAPE MODE
//No need to reverse width and height
Bitmap scaled = Bitmap.createScaledBitmap(bm, screenWidth,screenHeight , true);
MainActivity.imageBitmap = scaled;
}
Calendar c = Calendar.getInstance();
String time = Integer.toString(c.get(Calendar.DATE));
//MediaStore.Images.Media.insertImage(getContentResolver(), MainActivity.imageBitmap, time+"MyOCR", "Hello!!");
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/MyOCRApp");
if (! myDir.exists()){
if (! myDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return;
}
}
String fname = "Image-" +time+ ".jpg";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
MainActivity.imageBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
MediaStore.Images.Media.insertImage(getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());
} catch (Exception e) {
e.printStackTrace();
}
surfaceDestroyed(mSurfaceHolder);
}
};
This is the code in my camera class. I even debugged and checked that the picture was perfectly fine, when the tesseract APIs are called. I can't post photos, otherwise I have posted one. What should I do??
I am experimenting with tesseract on android as well. Try to rescale your image. An image taken by the camera activity maybe to big. Additionaly you probably have to pre-process the image (contrast, horizontal alignment of text, ...)
I have an app that I want to be able to capture a screenshot
Here is my code :
public class Screenshot {
private final View view;
/** Create snapshots based on the view and its children. */
public Screenshot(View root) {
this.view = root;
}
/** Create snapshot handler that captures the root of the whole activity. */
public Screenshot(Activity activity) {
final View contentView = activity.findViewById(android.R.id.content);
this.view = contentView.getRootView();
}
/** Take a snapshot of the view. */
public Bitmap snap() {
Bitmap bitmap = Bitmap.createBitmap(this.view.getWidth(), this.view.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
}
but the contents of the surfaceView is saved as black.!!!
Please help me, Thanks...
I hope you have used this solution which was posted here Get screenshot of surfaceView in Android
this thing is explained here Take Screenshot of SurfaceView
The SurfaceView's surface is independent of the surface on which View elements are drawn. So capturing the View contents won't include the SurfaceView.........
I hope this Taking screenshot programmatically doesnt capture the contents of surfaceVIew code can help you out more
public class Cam_View extends Activity implements SurfaceHolder.Callback {
protected static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0;
private SurfaceView SurView;
private SurfaceHolder camHolder;
private boolean previewRunning;
final Context context = this;
public static Camera camera = null;
private RelativeLayout CamView;
private Bitmap inputBMP = null, bmp, bmp1;
private ImageView mImage;
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
CamView = (RelativeLayout) findViewById(R.id.camview);//RELATIVELAYOUT OR
//ANY LAYOUT OF YOUR XML
SurView = (SurfaceView)findViewById(R.id.sview);//SURFACEVIEW FOR THE PREVIEW
//OF THE CAMERA FEED
camHolder = SurView.getHolder(); //NEEDED FOR THE PREVIEW
camHolder.addCallback(this); //NEEDED FOR THE PREVIEW
camHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//NEEDED FOR THE PREVIEW
camera_image = (ImageView) findViewById(R.id.camera_image);//NEEDED FOR THE PREVIEW
Button btn = (Button) findViewById(R.id.button1); //THE BUTTON FOR TAKING PICTURE
btn.setOnClickListener(new OnClickListener() { //THE BUTTON CODE
public void onClick(View v) {
camera.takePicture(null, null, mPicture);//TAKING THE PICTURE
//THE mPicture IS CALLED
//WHICH IS THE LAST METHOD(SEE BELOW)
}
});
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,//NEEDED FOR THE PREVIEW
int height) {
if(previewRunning) {
camera.stopPreview();
}
Camera.Parameters camParams = camera.getParameters();
Camera.Size size = camParams.getSupportedPreviewSizes().get(0);
camParams.setPreviewSize(size.width, size.height);
camera.setParameters(camParams);
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
previewRunning=true;
} catch(IOException e) {
e.printStackTrace();
}
}
public void surfaceCreated(SurfaceHolder holder) { //NEEDED FOR THE PREVIEW
try {
camera=Camera.open();
} catch(Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
finish();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) { //NEEDED FOR THE PREVIEW
camera.stopPreview();
camera.release();
camera=null;
}
public void TakeScreenshot(){ //THIS METHOD TAKES A SCREENSHOT AND SAVES IT AS .jpg
Random num = new Random();
int nu=num.nextInt(1000); //PRODUCING A RANDOM NUMBER FOR FILE NAME
CamView.setDrawingCacheEnabled(true); //CamView OR THE NAME OF YOUR LAYOUR
CamView.buildDrawingCache(true);
Bitmap bmp = Bitmap.createBitmap(CamView.getDrawingCache());
CamView.setDrawingCacheEnabled(false); // clear drawing cache
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 100, bos);
byte[] bitmapdata = bos.toByteArray();
ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);
String picId=String.valueOf(nu);
String myfile="Ghost"+picId+".jpeg";
File dir_image = new File(Environment.getExternalStorageDirectory()+//<---
File.separator+"Ultimate Entity Detector"); //<---
dir_image.mkdirs(); //<---
//^IN THESE 3 LINES YOU SET THE FOLDER PATH/NAME . HERE I CHOOSE TO SAVE
//THE FILE IN THE SD CARD IN THE FOLDER "Ultimate Entity Detector"
try {
File tmpFile = new File(dir_image,myfile);
FileOutputStream fos = new FileOutputStream(tmpFile);
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
Toast.makeText(getApplicationContext(),
"The file is saved at :SD/Ultimate Entity Detector",Toast.LENGTH_LONG).show();
bmp1 = null;
camera_image.setImageBitmap(bmp1); //RESETING THE PREVIEW
camera.startPreview(); //RESETING THE PREVIEW
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private PictureCallback mPicture = new PictureCallback() { //THIS METHOD AND THE METHOD BELOW
//CONVERT THE CAPTURED IMAGE IN A JPG FILE AND SAVE IT
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File dir_image2 = new File(Environment.getExternalStorageDirectory()+
File.separator+"Ultimate Entity Detector");
dir_image2.mkdirs(); //AGAIN CHOOSING FOLDER FOR THE PICTURE(WHICH IS LIKE A SURFACEVIEW
//SCREENSHOT)
File tmpFile = new File(dir_image2,"TempGhost.jpg"); //MAKING A FILE IN THE PATH
//dir_image2(SEE RIGHT ABOVE) AND NAMING IT "TempGhost.jpg" OR ANYTHING ELSE
try { //SAVING
FileOutputStream fos = new FileOutputStream(tmpFile);
fos.write(data);
fos.close();
//grabImage();
} catch (FileNotFoundException e) {
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
}
String path = (Environment.getExternalStorageDirectory()+
File.separator+"Ultimate EntityDetector"+
File.separator+"TempGhost.jpg");//<---
BitmapFactory.Options options = new BitmapFactory.Options();//<---
options.inPreferredConfig = Bitmap.Config.ARGB_8888;//<---
bmp1 = BitmapFactory.decodeFile(path, options);//<--- *********(SEE BELOW)
//THE LINES ABOVE READ THE FILE WE SAVED BEFORE AND CONVERT IT INTO A BitMap
camera_image.setImageBitmap(bmp1); //SETTING THE BitMap AS IMAGE IN AN IMAGEVIEW(SOMETHING
//LIKE A BACKGROUNG FOR THE LAYOUT)
tmpFile.delete();
TakeScreenshot();//CALLING THIS METHOD TO TAKE A SCREENSHOT
//********* THAT LINE MIGHT CAUSE A CRASH ON SOME PHONES (LIKE XPERIA T)<----(SEE HERE)
//IF THAT HAPPENDS USE THE LINE "bmp1 =decodeFile(tmpFile);" WITH THE METHOD BELOW
}
};
public Bitmap decodeFile(File f) { //FUNCTION BY Arshad Parwez
Bitmap b = null;
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
int IMAGE_MAX_SIZE = 1000;
int scale = 1;
if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
scale = (int) Math.pow(
2,
(int) Math.round(Math.log(IMAGE_MAX_SIZE
/ (double) Math.max(o.outHeight, o.outWidth))
/ Math.log(0.5)));
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
return b;
}
}
try out this also
public static Bitmap overlay(Bitmap bmp1,Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, 0,0, null);
canvas.drawBitmap(bmp2, 0, 0, null);
Log.i("bmOverlay.......",""+bmOverlay);
bmp3=bmOverlay;
return bmOverlay;
}
private void getScreen() {
Toast.makeText(BookType1.this, "saved", Toast.LENGTH_SHORT).show();
File myDir=new File("/sdcard/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".png";
File file = new File (myDir, fname);
try
{
FileOutputStream ostream = new FileOutputStream(file);
bmp3.compress(CompressFormat.PNG, 100, ostream);
ostream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
and you can also go through these references which gives you more idea
How to capture screenshot of surfaceview with background
Taking screen shot of a SurfaceView in android
How to take a screenshot of Android's Surface View?
How to programmatically take a screenshot in Android?
I want to use barcode scanner into my application and i am using Zbar library
however, i can scan barcode but i want to save scanned image into sd card.
So far, i can able to capture image and save into SD but when i try to open it i have broken image error and cannot display it.
What am i using is :
private final Camera.PreviewCallback saveImage = new Camera.PreviewCallback()
{
#Override
public void onPreviewFrame(byte[] data, Camera camera)
{
mCamera.setPreviewCallback(null);
String path = Environment.getExternalStorageDirectory() + "/DCIM/mcs_" + timeStamp + ".jpg";
FileOutputStream fos = null;
try
{
fos = new FileOutputStream(path);
fos.write(data);
fos.close();
}
catch(Exception e)
{
}
}
};
PreviewCallback previewCb = new PreviewCallback()
{
public void onPreviewFrame(byte[] data, Camera camera)
{
Camera.Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
Image barcode = new Image(size.width, size.height);
barcode.setData(data);
barcode = barcode.convert("Y800");
int result = scanner.scanImage(barcode);
if (result != 0)
{
mCamera.setPreviewCallback(saveImage);
mCamera.stopPreview();
SymbolSet syms = scanner.getResults();
for (Symbol sym : syms)
{
Intent intent = new Intent(getApplicationContext(), ScanCodeResult.class);
intent.putExtra("timeStamp", timeStamp);
intent.putExtra("result", sym.getData().toString());
//startActivity(intent);
break;
}
}
}
};
#Override
public void onPreviewFrame(byte[] data, Camera camera)
{
Size size = camera.getParameters().getPreviewSize(); //获取预览大小
final int w = size.width; //宽度
final int h = size.height;
final YuvImage image = new YuvImage(data, ImageFormat.NV21, w, h, null);
ByteArrayOutputStream os = new ByteArrayOutputStream(data.length);
if(!image.compressToJpeg(new Rect(0, 0, w, h), 100, os)){
return;
}
byte[] tmp = os.toByteArray();
Bitmap bmp = BitmapFactory.decodeByteArray(tmp, 0,tmp.length);
FileHelper fileHelper = new FileHelper();
fileHelper.storeInSD(bmp);
}
I have an app that I want to be able to capture a screenshot. The background of the layout is a surfaceView that shows video from the rear camera. The following code is able to take a screenshot but the contents of the surfaceView is saved as black. Here is the code :
btn.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Random num = new Random();
int nu=num.nextInt(1000);
Bitmap bmp;
CamView.setDrawingCacheEnabled(true);
CamView.buildDrawingCache(true);
Bitmap bmp2 = Bitmap.createBitmap(CamView.getDrawingCache()); //Screenshot of the layout
CamView.setDrawingCacheEnabled(false);
SurView.setDrawingCacheEnabled(true);
SurView.buildDrawingCache(true);
Bitmap bmp1 = Bitmap.createBitmap(SurView.getDrawingCache()); //Screenshot of the surfaceView
SurView.setDrawingCacheEnabled(false);
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(),bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay); //Overlaying the 2 bitmaps
canvas.drawBitmap(bmp1, 0,0, null);
canvas.drawBitmap(bmp2, 0,0, null);
bmp=bmOverlay;
//saving the file
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 100, bos);
byte[] bitmapdata = bos.toByteArray();
ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);
String picId=String.valueOf(nu);
String myfile="Ghost"+picId+".jpeg";
File dir_image = new File(Environment.getExternalStorageDirectory()+
File.separator+"Ultimate Entity Detector");
dir_image.mkdirs();
try {
File tmpFile = new File(dir_image,myfile);
FileOutputStream fos = new FileOutputStream(tmpFile);
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
I updated the code. Now i create 2 bitmaps, 1 for the layout xml and 1 for the surfaceView and then i overlay them into a single bitmap. But the surfaceView bitmap is still black
I finally solved this . Below i give some code for anyone who wants to know how to take screenshots of a layout ,pictures from the camera without intent, screenshots(sort of) of the content of a surfaceView and save the screen shot in a folder :
public class Cam_View extends Activity implements SurfaceHolder.Callback {
protected static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0;
private SurfaceView SurView;
private SurfaceHolder camHolder;
private boolean previewRunning;
final Context context = this;
public static Camera camera = null;
private RelativeLayout CamView;
private Bitmap inputBMP = null, bmp, bmp1;
private ImageView mImage;
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
CamView = (RelativeLayout) findViewById(R.id.camview);//RELATIVELAYOUT OR
//ANY LAYOUT OF YOUR XML
SurView = (SurfaceView)findViewById(R.id.sview);//SURFACEVIEW FOR THE PREVIEW
//OF THE CAMERA FEED
camHolder = SurView.getHolder(); //NEEDED FOR THE PREVIEW
camHolder.addCallback(this); //NEEDED FOR THE PREVIEW
camHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//NEEDED FOR THE PREVIEW
camera_image = (ImageView) findViewById(R.id.camera_image);//NEEDED FOR THE PREVIEW
Button btn = (Button) findViewById(R.id.button1); //THE BUTTON FOR TAKING PICTURE
btn.setOnClickListener(new OnClickListener() { //THE BUTTON CODE
public void onClick(View v) {
camera.takePicture(null, null, mPicture);//TAKING THE PICTURE
//THE mPicture IS CALLED
//WHICH IS THE LAST METHOD(SEE BELOW)
}
});
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,//NEEDED FOR THE PREVIEW
int height) {
if(previewRunning) {
camera.stopPreview();
}
Camera.Parameters camParams = camera.getParameters();
Camera.Size size = camParams.getSupportedPreviewSizes().get(0);
camParams.setPreviewSize(size.width, size.height);
camera.setParameters(camParams);
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
previewRunning=true;
} catch(IOException e) {
e.printStackTrace();
}
}
public void surfaceCreated(SurfaceHolder holder) { //NEEDED FOR THE PREVIEW
try {
camera=Camera.open();
} catch(Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
finish();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) { //NEEDED FOR THE PREVIEW
camera.stopPreview();
camera.release();
camera=null;
}
public void TakeScreenshot(){ //THIS METHOD TAKES A SCREENSHOT AND SAVES IT AS .jpg
Random num = new Random();
int nu=num.nextInt(1000); //PRODUCING A RANDOM NUMBER FOR FILE NAME
CamView.setDrawingCacheEnabled(true); //CamView OR THE NAME OF YOUR LAYOUR
CamView.buildDrawingCache(true);
Bitmap bmp = Bitmap.createBitmap(CamView.getDrawingCache());
CamView.setDrawingCacheEnabled(false); // clear drawing cache
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 100, bos);
byte[] bitmapdata = bos.toByteArray();
ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);
String picId=String.valueOf(nu);
String myfile="Ghost"+picId+".jpeg";
File dir_image = new File(Environment.getExternalStorageDirectory()+//<---
File.separator+"Ultimate Entity Detector"); //<---
dir_image.mkdirs(); //<---
//^IN THESE 3 LINES YOU SET THE FOLDER PATH/NAME . HERE I CHOOSE TO SAVE
//THE FILE IN THE SD CARD IN THE FOLDER "Ultimate Entity Detector"
try {
File tmpFile = new File(dir_image,myfile);
FileOutputStream fos = new FileOutputStream(tmpFile);
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
Toast.makeText(getApplicationContext(),
"The file is saved at :SD/Ultimate Entity Detector",Toast.LENGTH_LONG).show();
bmp1 = null;
camera_image.setImageBitmap(bmp1); //RESETING THE PREVIEW
camera.startPreview(); //RESETING THE PREVIEW
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private PictureCallback mPicture = new PictureCallback() { //THIS METHOD AND THE METHOD BELOW
//CONVERT THE CAPTURED IMAGE IN A JPG FILE AND SAVE IT
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File dir_image2 = new File(Environment.getExternalStorageDirectory()+
File.separator+"Ultimate Entity Detector");
dir_image2.mkdirs(); //AGAIN CHOOSING FOLDER FOR THE PICTURE(WHICH IS LIKE A SURFACEVIEW
//SCREENSHOT)
File tmpFile = new File(dir_image2,"TempGhost.jpg"); //MAKING A FILE IN THE PATH
//dir_image2(SEE RIGHT ABOVE) AND NAMING IT "TempGhost.jpg" OR ANYTHING ELSE
try { //SAVING
FileOutputStream fos = new FileOutputStream(tmpFile);
fos.write(data);
fos.close();
//grabImage();
} catch (FileNotFoundException e) {
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
}
String path = (Environment.getExternalStorageDirectory()+
File.separator+"Ultimate EntityDetector"+
File.separator+"TempGhost.jpg");//<---
BitmapFactory.Options options = new BitmapFactory.Options();//<---
options.inPreferredConfig = Bitmap.Config.ARGB_8888;//<---
bmp1 = BitmapFactory.decodeFile(path, options);//<--- *********(SEE BELOW)
//THE LINES ABOVE READ THE FILE WE SAVED BEFORE AND CONVERT IT INTO A BitMap
camera_image.setImageBitmap(bmp1); //SETTING THE BitMap AS IMAGE IN AN IMAGEVIEW(SOMETHING
//LIKE A BACKGROUNG FOR THE LAYOUT)
tmpFile.delete();
TakeScreenshot();//CALLING THIS METHOD TO TAKE A SCREENSHOT
//********* THAT LINE MIGHT CAUSE A CRASH ON SOME PHONES (LIKE XPERIA T)<----(SEE HERE)
//IF THAT HAPPENDS USE THE LINE "bmp1 =decodeFile(tmpFile);" WITH THE METHOD BELOW
}
};
public Bitmap decodeFile(File f) { //FUNCTION BY Arshad Parwez
Bitmap b = null;
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
int IMAGE_MAX_SIZE = 1000;
int scale = 1;
if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
scale = (int) Math.pow(
2,
(int) Math.round(Math.log(IMAGE_MAX_SIZE
/ (double) Math.max(o.outHeight, o.outWidth))
/ Math.log(0.5)));
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
return b;
}
}
If you want to take a simple screenshot(no camera feed is needed) the you can use the TakeScreenshot method alone.
If you want to take a screenshot of a surfaceView with is not possible to do from the surfaceview directly the use the mPicture, set the picture you capture as backgroung , and then call TakeScreenshot to take your screenshot.(as seen above)
If you want to take a picture with the camera without calling an other camera app with an intent the use the takePicture with the mPicture and the surfaceView stuff from the code above.
What the previous code does if used "as is" is to take a screenshot of the layout contents(buttons,imageviews etc) and set as backgroung an image from the camera.
Below i also provide a basic layout xml for the previous code :
<?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:id="#+id/camview">
<SurfaceView
android:id="#+id/sview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<ImageView
android:id="#+id/camera_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="#string/app_name" />
<Button
android:id="#+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
</RelativeLayout>
Dont forget to import what needs to be imported
According to the comment (https://groups.google.com/forum/#!topic/android-developers/jYjvm7ItpXQ) by an Android Framework engineer, SurfaceView isn't treated like a normal view:
The surface view is actually BEHIND your window, and a hole punched in
the window for you to see it. You thus can put things on top of it in
your window, but nothing in your window can appear behind it.
Since it's "BEHIND" the app window, consequently the drawing for the window's view wouldn't contain it. I suppose the only way then is to provide a method in your SurfaceView class to draw its own content to the provided Canvas/Bitmap.
I am working on an app that needs to access an array of pixels from a picture after it is taken. The main Activity is below. I have a good amount of java experience but extremely limited experience with images past displaying them on the screen. I see the byte array being passed to the picture callback method but I do not know how it is formatted. How can I get a pixel array that includes the RGB components from the captured image? I tried to find this through the stack overflow forums however I got a few hundred pages of results and only searched through the first 10 or so, so I am sorry if that has already been asked and I just did not see it.
public class ConverterActivity extends Activity
{
private Camera mCamera;
private CameraPreview mPreview;
private PictureCallback mPicture = new PictureCallback() {
private String TAG;
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
// Log.d(TAG, "Error creating media file, check storage permissions: " +
// e.getMessage());
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
// Create an instance of Camera
mCamera = Camera.open(this.getBackCamera());
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
}
#Override
protected void onPause()
{
super.onPause();
releaseCamera(); // release the camera immediately on pause event
}
private void releaseCamera(){
if (mCamera != null){
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
public int getBackCamera()
{
int numCameras = Camera.getNumberOfCameras();
CameraInfo cInfo = new CameraInfo();
for (int i = 0; i < numCameras; i++)
{
Camera.getCameraInfo(i, cInfo);
if (cInfo.facing == CameraInfo.CAMERA_FACING_BACK)
{
return i;
}
}
return -1;
}
}
If you take the picture using code like this:
imgFile = new File(Environment.getExternalStorageDirectory () + "/somefolder/" + name + ".jpg");
String fileName = imgFile.getAbsolutePath();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(fileName)));
startActivityForResult(intent, REQUEST_FROM_CAMERA);
Then you should be able to, when you get the result back from this intent, using code like this to access the bitmap
if (imgFile.exists()) {
String fileName = file.getAbsolutePath();
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm;
opts.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(fileName, opts);
return bm;
}
else return null;
Then you can use bitmapfactory tools, such as compress to stream and then
convert to byte[]
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, stream); // 100 = max quality
byte[] byteArray = stream.toByteArray();