I'm posting the example and it makes a photo and let you see the preview but i have a problem: The issue is that if you try this code you'll see the preview but it is not oriented correctly please is there someone who can solve this?
public class MainActivity extends ActionBarActivity {
private ImageSurfaceView mImageSurfaceView;
private Camera camera;
private FrameLayout cameraPreviewLayout;
private ImageView capturedImageHolder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
cameraPreviewLayout = (FrameLayout)findViewById(R.id.camera_preview);
capturedImageHolder = (ImageView)findViewById(R.id.captured_image);
camera = checkDeviceCamera();
mImageSurfaceView = new ImageSurfaceView(MainActivity.this, camera);
cameraPreviewLayout.addView(mImageSurfaceView);
Button captureButton = (Button)findViewById(R.id.button);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
camera.takePicture(null, null, pictureCallback);
}
});
}
private Camera checkDeviceCamera(){
Camera mCamera = null;
try {
mCamera = Camera.open();
} catch (Exception e) {
e.printStackTrace();
}
return mCamera;
}
PictureCallback pictureCallback = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
if(bitmap==null){
Toast.makeText(MainActivity.this, "Captured image is empty", Toast.LENGTH_LONG).show();
return;
}
capturedImageHolder.setImageBitmap(scaleDownBitmapImage(bitmap, 300, 200 ));
}
};
private Bitmap scaleDownBitmapImage(Bitmap bitmap, int newWidth, int newHeight){
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
return resizedBitmap;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
ImageSurfaceView Class
public class ImageSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private Camera camera;
private SurfaceHolder surfaceHolder;
public ImageSurfaceView(Context context, Camera camera) {
super(context);
this.camera = camera;
this.surfaceHolder = getHolder();
this.surfaceHolder.addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
this.camera.setPreviewDisplay(holder);
this.camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
this.camera.stopPreview();
this.camera.release();
}
}
XML
<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=".MainActivity"
android:baselineAligned="false">
<FrameLayout
android:id="#+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="300dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/capture_button"
android:id="#+id/button"
android:layout_below="#+id/camera_preview"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/captured_image"
android:layout_below="#+id/button"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="15dp"
android:contentDescription="#string/desc" />
The issue is that if you try this code you'll see the preview but it is not oriented correctly please is there someone who can solve this?
You have to user Exifinterface and Matrix to get the right orientation.
try this:
public static void handleImageRotation(Context context, File mFileTemp) {
if (!mFileTemp.exists()) {
Toast.makeText(context, "File not found", Toast.LENGTH_SHORT).show();
return;
}
ExifInterface exif = null;
int orientation = ExifInterface.ORIENTATION_NORMAL;
try {
exif = new ExifInterface(mFileTemp.getAbsolutePath());
orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
} catch (Exception e) {
e.printStackTrace();
}
Bitmap temp = BitmapFactory.decodeFile(mFileTemp.getAbsolutePath());
if (temp == null) Log.e(TAG, "Bitmap from File is null");
Matrix matrix = new Matrix();
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
matrix.postRotate(90);
temp = Bitmap.createBitmap(temp, 0, 0, temp.getWidth(), temp.getHeight(), matrix, true);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
matrix.postRotate(180);
temp = Bitmap.createBitmap(temp, 0, 0, temp.getWidth(), temp.getHeight(), matrix, true);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
matrix.postRotate(270);
temp = Bitmap.createBitmap(temp, 0, 0, temp.getWidth(), temp.getHeight(), matrix, true);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
temp.compress(Bitmap.CompressFormat.JPEG, 40, bos);
byte[] bitmapdata = bos.toByteArray();
// write the bytes in file
try {
FileOutputStream fos = new FileOutputStream(mFileTemp);
fos.write(bitmapdata);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
This is the code in question:
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
Camera.Parameters parameters = camera.getParameters();
parameters.setRotation(270); //set rotation to save the picture
camera.setDisplayOrientation(90);
//set the rotation for preview camera
camera.setParameters(parameters);
this.camera.setPreviewDisplay(holder);
this.camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
Related
I am creating a multi-image capturing feature using custom Camera in my app.But there is a problem with the custom camera. Image captured by custom camera is not getting clear as like default camera(Camera opening with Intent)
Please help me out.I have tried the lot of suggested solutions.
CameraActivity.java
public class CameraActivity extends Activity {
private Camera mCamera;
private SharedPreferences prefs;
private String clickedMenuItem;
Button captureButton;
private LayoutInflater controlInflater = null;
private View viewControl;
private CircularImageView imgview;
private ArrayList<Bitmap> bitmapArray = new ArrayList<Bitmap>();;
private ImageView cancleimg;
private FrameLayout imgLayout;
int RESULT_IMG = 200;
int NO_IMG = 204;
FrameLayout preview;
private CameraPreview mCameraPreview;
ArrayList<CharSequence> imgarrayList = new ArrayList<CharSequence>();
Intent intent = new Intent( );
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_preview);
clickedMenuItem = Attributes.Another_Item;
if(getIntent().hasExtra(Attributes.ClickedMenuItem)){
clickedMenuItem = getIntent().getExtras().getString(Attributes.ClickedMenuItem);
}
mCamera = getCameraInstance();
mCameraPreview = new CameraPreview(this, mCamera);
preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
try{
controlInflater = LayoutInflater.from(getBaseContext());
viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl
= new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
}catch(Exception e)
{e.printStackTrace();}
captureButton = (Button)viewControl.findViewById(R.id.button_capture);
Button doneBtn = (Button)viewControl.findViewById(R.id.done);
imgview = (CircularImageView)viewControl.findViewById(R.id.captureimg);
cancleimg = (ImageView)viewControl.findViewById(R.id.cancleimg);
imgLayout = (FrameLayout)viewControl.findViewById(R.id.imglayout);
imgLayout.setVisibility(View.INVISIBLE);
if (isDIYUSer() && clickedMenuItem != null && !clickedMenuItem.equals(Attributes.Kagazz_Scanner)) {
captureButton.setBackgroundResource(R.drawable.cam);
}
cancleBtnClick();
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.takePicture(null, null, mPicture);
}
});
doneBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
setResult(RESULT_IMG,intent);
bitmapArray = null;
finish();
}
});
}
#Override
public void onPause() {
try{
super.onPause();
releaseCamera();
}catch(Exception e)
{}// release the camera immediately on pause event
}
private void releaseCamera(){
try{
if (mCamera != null){
mCamera.stopPreview();
mCamera.setPreviewCallback(null);// stop the preview
mCamera.release();
preview.removeView(mCameraPreview);
mCamera = null;
// release the camera for other applicationsCODE_IMG
}
}
catch(Exception e)
{}
}
#Override
public void onBackPressed() {
imgarrayList.clear();
intent.putCharSequenceArrayListExtra("List",imgarrayList);
setResult(RESULT_IMG,intent);
finish();
}
void cancleImg()
{}
public void deleteTempImg(Uri uri)
{
try {
File file = new File(uri.getPath());
boolean isdeleted = file.delete();
if(file.exists()){
boolean deleted = file.getCanonicalFile().delete();
if(deleted)
{Log.d("tag", "file deleted.");}
}
if(file.exists()){
this.getApplicationContext().deleteFile(file.getName());
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onResume() {
super.onResume();
try{
if (mCamera == null)
{
mCamera = getCameraInstance();
// three new lines, creating a new CameraPreview, then adding it to the FrameLayout
mCameraPreview = new CameraPreview(this, mCamera);
preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
}
}catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Helper method to access the camera returns null if it cannot get the
* camera or does not exist
*
* #return
*/
private Camera getCameraInstance() {
mCamera = null;
try {
mCamera = Camera.open();
//STEP #1: Get rotation degrees
// Camera.CameraInfo info = new Camera.CameraInfo();
// Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);
// int rotation = this.getWindowManager().getDefaultDisplay().getRotation();
// int degrees = 0;
// switch (rotation) {
// case Surface.ROTATION_0: degrees = 0; break; //Natural orientation
// case Surface.ROTATION_90: degrees = 90; break; //Landscape left
// case Surface.ROTATION_180: degrees = 180; break;//Upside down
// case Surface.ROTATION_270: degrees = 270; break;//Landscape right
// }
// int rotate = (info.orientation - degrees + 360) % 360;
//STEP #2: Set the 'rotation' parameter
Camera.Parameters params = mCamera.getParameters();
// params.setRotation(rotate);
/* Set Auto focus */
List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
// set the focus mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// set Camera parameters
}
else{
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
mCamera.setParameters(params);
} catch (Exception e) {
// cannot get camera or does not exist
}
return mCamera;
}
private static File getOutputMediaFile() {
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"MyCameraApp");
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;
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
public static Bitmap rotate(Bitmap bitmap, int degree) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
// mtx.postRotate(degree);
mtx.setRotate(degree);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
#Override
protected void onStop() {
super.onStop();
}
}
CameraPreview.java
public class CameraPreview extends SurfaceView implements
SurfaceHolder.Callback {
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
private LayoutInflater controlInflater = null;
// Constructor that obtains context and camera
#SuppressWarnings("deprecation")
public CameraPreview(Context context, Camera camera) {
super(context);
this.mCamera = camera;
this.mSurfaceHolder = this.getHolder();
this.mSurfaceHolder.addCallback(this);
this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
#SuppressWarnings("deprecation")
Camera.Parameters parameters = mCamera.getParameters();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
parameters.set("orientation", "portrait");
mCamera.setDisplayOrientation(90);
parameters.setRotation(90);
}
else {
// This is an undocumented although widely known feature
parameters.set("orientation", "landscape");
// For Android 2.2 and above
mCamera.setDisplayOrientation(0);
// Uncomment for Android 2.0 and above
parameters.setRotation(0);
}
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
}
}
#SuppressWarnings("deprecation")
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
try{
surfaceHolder.removeCallback(this);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}catch(Exception e)
{
if(e!=null)
e.printStackTrace();}
}
#SuppressWarnings("deprecation")
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format,
int width, int height) {
// start preview with new settings
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (Exception e) {
// intentionally left blank for a test
}
}
}
I write program, camera for android. I use next code
package camera;
public class SurfaceCamera extends Activity implements SurfaceHolder.Callback {
TextView testView;
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
PictureCallback rawCallback;
ShutterCallback shutterCallback;
PictureCallback jpegCallback;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_surf);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format("/sdcard/Octopus/gif/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Toast.makeText(getApplicationContext(), "Picture Saved", 2000).show();
refreshCamera();
}
};
}
public void captureImage(View v) throws IOException {
//take the picture
camera.takePicture(null, null, jpegCallback);
}
public void refreshCamera() {
if (surfaceHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
camera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
refreshCamera();
}
public void surfaceCreated(SurfaceHolder holder) {
try {
// open the camera
camera = Camera.open();
} catch (RuntimeException e) {
// check for exceptions
System.err.println(e);
return;
}
Camera.Parameters param;
param = camera.getParameters();
//param.setColorEffect(Camera.Parameters.EFFECT_NEGATIVE);
// modify parameter
param.setPreviewSize(600, 900);
camera.setDisplayOrientation(90);
camera.setParameters(param);
try {
// The Surface has been created, now tell the camera where to draw
// the preview.
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
// check for exceptions
System.err.println(e);
return;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// stop preview and release camera
camera.stopPreview();
camera.release();
camera = null;
}
}
layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.javacodegeeks.androidsurfaceviewexample.AndroidSurfaceviewExample" >
<SurfaceView
android:id="#+id/surfaceView"
android:layout_width="300dp"
android:layout_height="200dp" />
<LinearLayout
android:id="#+id/capture"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:gravity="center"
android:onClick="captureImage"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:text="Capture"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
</LinearLayout>
Where I see on surface image (on surface) the picture is distorted, stretched at the corners https://www.dropbox.com/s/ul5enua7tb07zkr/shot_000002.png?dl=0
but if I capture photo all ok https://www.dropbox.com/s/zibn89tl38a8eur/1424809721079.jpg?dl=0
Please help, what I write wrong? How I can fix it?
Thank you.
I'm going to develop an android application using BeyondAR framework. I try to use a CameraView component at the first half of the screen (app running only in portrait mode), but when i rotate camera 90 degrees image stretches and aspect ratio is wrong.Any help?
CameraView class (Beyondar framework)
public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
Camera.PictureCallback {
/**
*
* #author Joan Puig Sanz (joanpuigsanz#gmail.com)
*
*/
public static interface IPictureCallback {
/**
* This method is called when the snapshot of the camera is ready. If
* there is an error, the image will be null
*
* #param picture
*/
void onPictureTaken(Bitmap picture);
}
private SurfaceHolder mHolder;
private Camera mCamera;
private IPictureCallback mCameraCallback;
private BitmapFactory.Options mOptions;
private Size mPreviewSize;
private List<Size> mSupportedPreviewSizes;
private List<String> mSupportedFlashModes;
public CameraView(Context context) {
super(context);
init(context);
}
public CameraView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
mHolder = getHolder();
mHolder.addCallback(this);
try {
mCamera = Camera.open();
//mCamera.setDisplayOrientation(90);
//Camera.Parameters params = mCamera.getParameters();
//params.setPreviewSize(427, 1240);
//mCamera.setParameters(params);
setCamera(mCamera);
} catch (Exception e) {
Log.e(Constants.TAG, "ERROR: Unable to open the camera", e);
}
if (android.os.Build.VERSION.SDK_INT <= 10) {// Android 2.3.x or lower
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
}
public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
mSupportedFlashModes = mCamera.getParameters().getSupportedFlashModes();
// Set the camera to Auto Flash mode.
if (mSupportedFlashModes != null
&& mSupportedFlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO)) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
//parameters.setPreviewSize(300, 200);
mCamera.setParameters(parameters);
}
}
}
public void setSupportedPreviewSizes(List<Size> supportedPreviewSizes) {
mSupportedPreviewSizes = supportedPreviewSizes;
}
public Size getPreviewSize() {
return mPreviewSize;
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
try {
if (mCamera == null) {
init(getContext());
if (mCamera == null) {
return;
}
}
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
if (mCamera != null) {
mCamera.release();
}
mCamera = null;
Log.e(Constants.TAG, "CameraView -- ERROR en SurfaceCreated", exception);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
// Because the CameraDevice object is not a shared resource, it's very
// important to release it when the activity is paused.
if (mCamera == null) {
return;
}
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private Size getOptimalPreviewSize(List<Size> sizes, int width, int height) {
Size result = null;
for (Camera.Size size : sizes) {
if (size.width <= width && size.height <= height) {
if (result == null) {
result = size;
} else {
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea) {
result = size;
}
}
}
}
return result;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mCamera == null || getPreviewSize() == null) {
return;
}
Camera.Parameters parameters = mCamera.getParameters();
Size previewSize = getPreviewSize();
parameters.setPreviewSize(previewSize.width, previewSize.height);
mCamera.setParameters(parameters);
previewCamera();
}
#Override
public void onPictureTaken(byte[] imageData, Camera camera) {
if (imageData != null && mCameraCallback != null) {
mCameraCallback.onPictureTaken(StoreByteImage(imageData));
}
previewCamera();
}
public void previewCamera() {
if (mCamera == null){
return;
}
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d(Constants.TAG, "Cannot start preview.", e);
}
}
private Bitmap StoreByteImage(byte[] imageData) {
Bitmap myImage = DebugBitmap.decodeByteArray(imageData, 0, imageData.length, mOptions);
imageData = null;
System.gc();
return myImage;
}
public void tackePicture(IPictureCallback cameraCallback) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
tackePicture(cameraCallback, options);
}
public void tackePicture(IPictureCallback cameraCallback, BitmapFactory.Options options) {
if (mCamera == null) {
return;
}
mCameraCallback = cameraCallback;
mCamera.takePicture(null, this, this);
mOptions = options;
}
}
Edit
MyLayout xml file
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:orientation="horizontal"
android:paddingBottom="#dimen/padding"
android:paddingLeft="#dimen/padding"
android:paddingRight="#dimen/padding"
android:paddingTop="#dimen/padding" >
<FrameLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.beyondar.android.opengl.views.BeyondarGLSurfaceView
android:id="#+id/customGLSurface"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.beyondar.android.views.CameraView
android:id="#+id/camera"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<TextView
android:id="#+id/labelText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Touch an AR Object"
android:background="#000000"
android:textColor="#FFFFFF"
/>
</FrameLayout>
</LinearLayout
If you look at the example application for BeyondAR, you can see that it has a similar problem in that the camera's image gets stretched to fill the screen and so doesn't have the proper aspect ratio in both landscape in portrait. This is a common problem when working with the camera preview since it locks to a particular orientation when you first start it.
In order to get that, you need to resize the view on rotation to an aspect ratio that matches the device's camera. Here's the official Android guide.
Notice the part specifically called "Set the Preview Orientation".
BeyondAR has been updated, now it is way easier thanks to fragments. Check the web page and update your library:
https://github.com/BeyondAR/beyondar
hi i'm making a photograph effect app.
So,i loaded bitmap from camera(i saved orginal image and then loaded) to glsurfaceview and applied some effects but i couldn't find a way of saving changed image as image file *.png or *.jpg.
i looked almost everywhere ,but they aren't usable for my app.. always force close when i try save.
Here is my code.
i found some save codes but i couldn't get work.
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<android.opengl.GLSurfaceView
android:id="#+id/effectsview"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.05" />
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</GridLayout>
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="1" >
<Button
android:id="#+id/button1"
android:layout_width="159dp"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_row="0"
android:onClick="saverenderedimage"
android:layout_gravity="left|top"
android:text="Save Image" />
<Button
android:id="#+id/Button01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="left|top"
android:onClick="gomain"
android:text="Go Main Menu without saving" />
<Button
android:id="#+id/button2"
android:layout_width="156dp"
android:layout_column="0"
android:layout_gravity="right|top"
android:layout_row="0"
android:onClick="sharedialog"
android:text="Share" />
</GridLayout>
</LinearLayout>
Effect selector and applier .java
public class Effects_selevtor extends Activity implements GLSurfaceView.Renderer {
i declared some strings ints (deleted)
String imagefilepath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/filename.jpg";
int mCurrentEffect;
public void setCurrentEffect(int effect) {
mCurrentEffect = effect;
}
public void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_effects_selevtor);
mEffectView = (GLSurfaceView) findViewById(R.id.effectsview);
mEffectView.setEGLContextClientVersion(2);
mEffectView.setRenderer(this);
mEffectView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
mCurrentEffect = R.id.none;
Uri imageFileUri = Uri.parse("file:///sdcard/filename.jpg");
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);
startActivityForResult(cameraIntent, 2);
}
public void gomain(View View) {
startActivity(new Intent(Effects_selevtor.this,HelloEffects.class));
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 2) {
try {
if (bitmap != null) {
bitmap.recycle();
}
GLES20.glGenTextures(2, mTextures, 0);
// Load input bitmap
Bitmap bitmap = BitmapFactory.decodeFile(imagefilepath);
mImageWidth = bitmap.getWidth();
mImageHeight = bitmap.getHeight();
mTexRenderer.updateTextureSize(mImageWidth, mImageHeight);
// Upload to texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
// Set texture parameters
GLToolbox.initTexParams();
Toast.makeText(getApplicationContext(), "Touch your phone's Menu button to select effects ", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static Bitmap SavePixels(int x, int y, int w, int h, GL10 gl)
{
int b[]=new int[w*(y+h)];
int bt[]=new int[w*h];
IntBuffer ib=IntBuffer.wrap(b);
ib.position(0);
gl.glReadPixels(x, 0, w, y+h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);
for(int i=0, k=0; i<h; i++, k++)
{//remember, that OpenGL bitmap is incompatible with Android bitmap
//and so, some correction need.
for(int j=0; j<w; j++)
{
int pix=b[i*w+j];
int pb=(pix>>16)&0xff;
int pr=(pix<<16)&0x00ff0000;
int pix1=(pix&0xff00ff00) | pr | pb;
bt[(h-k-1)*w+j]=pix1;
}
}
Bitmap sb=Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
return sb;
}
public static void SavePNG(int x, int y, int w, int h, String name, GL10 gl)
{
Bitmap bmp=SavePixels(x,y,w,h,gl);
try
{
FileOutputStream fos=new FileOutputStream("/sdcard/CamWay/"+name);
bmp.compress(CompressFormat.PNG, 100, fos);
try
{
fos.flush();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
try
{
fos.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void saverenderedimage(View view) {
//i tried save but it not worked i don't understand what should i declare for "gl"
SavePNG(0, 0,mEffectView.getWidth() , mEffectView.getHeight(), "CamWay.png", gl);
// SavePNG(0, 0,mEffectView.getWidth() , mEffectView.getHeight(), imagefilepath, gl);
startActivity(new Intent(Effects_selevtor.this,HelloEffects.class));
}
public void OnClickselector(View arg0) {
startActivity(new Intent(Effects_selevtor.this,HelloEffects.class));
}
private void loadTextures() {
// Generate textures
GLES20.glGenTextures(2, mTextures, 0);
// Load input bitmap
Bitmap bitmap = BitmapFactory.decodeFile(imagefilepath);
// Load input bitmap
mImageWidth = bitmap.getWidth();
mImageHeight = bitmap.getHeight();
mTexRenderer.updateTextureSize(mImageWidth, mImageHeight);
// Upload to texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
// Set texture parameters
GLToolbox.initTexParams();
}
private void initEffect() {
EffectFactory effectFactory = mEffectContext.getFactory();
if (mEffect != null) {
mEffect.release();
}
/**
* Initialize the correct effect based on the selected menu/action item
*/
switch (mCurrentEffect) {
case R.id.none:
break;
case R.id.vignette:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_VIGNETTE);
mEffect.setParameter("scale", .5f);
break;
//and a lot effect more i deleted for readability
default:
break;
}
}
private void applyEffect() {
mEffect.apply(mTextures[0], mImageWidth, mImageHeight, mTextures[1]);
}
private void renderResult() {
if (mCurrentEffect != R.id.none) {
// if no effect is chosen, just render the original bitmap
mTexRenderer.renderTexture(mTextures[1]);
}
else {
// render the result of applyEffect()
mTexRenderer.renderTexture(mTextures[0]);
}
}
#Override
public void onDrawFrame(GL10 gl) {
if (!mInitialized) {
//Only need to do this once
mEffectContext = EffectContext.createWithCurrentGlContext();
mTexRenderer.init();
loadTextures();
mInitialized = true;
}
if (mCurrentEffect != R.id.none) {
//if an effect is chosen initialize it and apply it to the texture
initEffect();
applyEffect();
}
renderResult();
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if (mTexRenderer != null) {
mTexRenderer.updateViewSize(width, height);
}
}
I achieved saving the GLSurfaceView as PNG by cross-compiling libpng and using it through JNI.
I have a canvas which I'm displaying a picture from the media store as its background and then I'm drawing on it. I'd like to save the background+what has been drawn over it but I'm only able to save the background, which is useless for me. I am trying to understand what I'm doing wrong. I basically did what people suggest here but it didn't help.
Here is the code which I have:
EDIT: THIS TIME I UPLOADED ALL THE CODE IN HERE
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.util.ArrayList;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.view.Display;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Toast;
public class CanvasDrawingActivity extends Activity {
private ArrayList<Path> _graphics = new ArrayList<Path>();
private Paint mPaint;
public static final int GET_FROM_GALLERY = 1;
public static final int IMAGE_CAPTURE = 0;
public static final int SELECT_IMAGE_FROM_DEVICE = 1;
public Bitmap myBitmap;
public int isFirstTime = 0;
public DrawingPanel mPanel;
static int id = 1;
public Uri fileUri ;
#Override
public void onCreate(Bundle savedInstanceState) {
mPanel = new DrawingPanel(this);
mPanel.setId(findId());
super.onCreate(savedInstanceState);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//https://stackoverflow.com/questions/10937659/android-image-doesnt-save-using-native-camera-app-on-nexus-s
File f = new File(Environment.getExternalStorageDirectory().getPath(), String.format("%d.jpg", System.currentTimeMillis()));
fileUri= Uri.fromFile(f);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, IMAGE_CAPTURE);
setContentView(R.layout.main);
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.save:
savePicture();
return true;
case R.id.clear:
// startActivity(new Intent(this, Clear.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void savePicture(){
long now = System.currentTimeMillis();
OutputStream fos;
try {
fos = new FileOutputStream(String.format(Environment.getExternalStorageDirectory().getAbsolutePath()+"/edited_%d.jpg",now));
myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finish(); //close the activity.
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
//Detects request codes
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == IMAGE_CAPTURE && resultCode == RESULT_OK) {
Uri result;
result = fileUri;
//refresh storage
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
try {
myBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), result);
startDrawing();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if (resultCode == Activity.RESULT_CANCELED){
}
}
public void startDrawing(){
setContentView(mPanel);
mPaint = new Paint();
mPaint.setDither(true);
mPaint.setColor(0xFFFFFF00);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(3);
}
public int findId(){
View v = findViewById(id);
while (v != null){
v = findViewById(++id);
}
return id++;
}
class DrawingPanel extends SurfaceView implements SurfaceHolder.Callback {
private DrawingThread _thread;
private Path path;
public DrawingPanel(Context context) {
super(context);
setDrawingCacheEnabled(true);
getHolder().addCallback(this);
_thread = new DrawingThread(getHolder(), this);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
synchronized (_thread.getSurfaceHolder()) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
path = new Path();
path.moveTo(event.getX(), event.getY());
path.lineTo(event.getX(), event.getY());
}else if(event.getAction() == MotionEvent.ACTION_MOVE){
path.lineTo(event.getX(), event.getY());
if(_graphics.size() > 0) {
_graphics.remove(_graphics.size() - 1);
}
_graphics.add(path);
}else if(event.getAction() == MotionEvent.ACTION_UP){
path.lineTo(event.getX(), event.getY());
_graphics.remove(_graphics.size() - 1);
_graphics.add(path);
}
return true;
}
}
//Source: http://thinkandroid.wordpress.com/2009/12/25/resizing-a-bitmap/
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
/**
* Converts a immutable bitmap to a mutable bitmap. This operation doesn't allocates
* more memory that there is already allocated.
*
* #param imgIn - Source image. It will be released, and should not be used more
* #return a copy of imgIn, but muttable.
*/
public Bitmap convertToMutable(Bitmap imgIn) {
try {
//this is the file going to use temporally to save the bytes.
// This file will not be a image, it will store the raw image data.
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "temp.tmp");
//Open an RandomAccessFile
//Make sure you have added uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
//into AndroidManifest.xml file
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
// get the width and height of the source bitmap.
int width = imgIn.getWidth();
int height = imgIn.getHeight();
Config type = imgIn.getConfig();
//Copy the byte to the file
//Assume source bitmap loaded using options.inPreferredConfig = Config.ARGB_8888;
FileChannel channel = randomAccessFile.getChannel();
MappedByteBuffer map = channel.map(MapMode.READ_WRITE, 0, imgIn.getRowBytes()*height);
imgIn.copyPixelsToBuffer(map);
//recycle the source bitmap, this will be no longer used.
imgIn.recycle();
System.gc();// try to force the bytes from the imgIn to be released
//Create a new bitmap to load the bitmap again. Probably the memory will be available.
imgIn = Bitmap.createBitmap(width, height, type);
map.position(0);
//load it back from temporary
imgIn.copyPixelsFromBuffer(map);
//close the temporary file and channel , then delete that also
channel.close();
randomAccessFile.close();
// delete the temp file
file.delete();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return imgIn;
}
#Override
public void onDraw(Canvas canvas) {
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
myBitmap = getResizedBitmap(myBitmap, height, width);
if (isFirstTime<3){
myBitmap = convertToMutable(myBitmap);
canvas.drawBitmap(myBitmap, 0, 0, null);
isFirstTime++;
}
for (Path path : _graphics) {
//canvas.drawPoint(graphic.x, graphic.y, mPaint);
canvas.drawPath(path, mPaint);
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
_thread.setRunning(true);
_thread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
class DrawingThread extends Thread {
private SurfaceHolder _surfaceHolder;
private DrawingPanel _panel;
private boolean _run = false;
public DrawingThread(SurfaceHolder surfaceHolder, DrawingPanel panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
public SurfaceHolder getSurfaceHolder() {
return _surfaceHolder;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
if (c!=null)
_panel.onDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}
This is main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="#+id/main_view">
</LinearLayout>
and menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/save"
android:title="Save"/>
<item
android:id="#+id/clear"
android:title="Clear"/>
</menu>
Any help would be appreciated. Thanks!!
EDIT: I got it to work!! Here it is!
#Override
public void onCreate(Bundle savedInstanceState) {
mPanel = new DrawingPanel(this);
mPanel.setId(findId());
super.onCreate(savedInstanceState);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//https://stackoverflow.com/questions/10937659/android-image-doesnt-save-using-native-camera-app-on-nexus-s
File f = new File(Environment.getExternalStorageDirectory().getPath(), String.format("%d.jpg", System.currentTimeMillis()));
fileUri= Uri.fromFile(f);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, IMAGE_CAPTURE);
setContentView(R.layout.main);
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.save:
savePicture();
return true;
case R.id.clear:
// startActivity(new Intent(this, Clear.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void savePicture(){
long now = System.currentTimeMillis();
OutputStream fos;
try {
//SAVE THIS ONE- replicate all paths
Canvas canvas = new Canvas(myBitmap);
for (Path path : _graphicsToSave)
{
canvas.drawPath(path, mPaint);
}
fos = new FileOutputStream(String.format(Environment.getExternalStorageDirectory().getAbsolutePath()+"/edited_%d.jpg",now));
myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finish(); //close the activity.
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
//Detects request codes
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == IMAGE_CAPTURE && resultCode == RESULT_OK) {
Uri result;
result = fileUri;
//refresh storage
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
try {
myBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), result);
//resize the picture to match the screen size
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
myBitmap = getResizedBitmap(myBitmap, height, width);
startDrawing();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if (resultCode == Activity.RESULT_CANCELED){
}
}
//Source: http://thinkandroid.wordpress.com/2009/12/25/resizing-a-bitmap/
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
public void startDrawing(){
setContentView(mPanel);
mPaint = new Paint();
mPaint.setDither(true);
mPaint.setColor(0xFFFFFF00);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(3);
}
public int findId(){
View v = findViewById(id);
while (v != null){
v = findViewById(++id);
}
return id++;
}
class DrawingPanel extends SurfaceView implements SurfaceHolder.Callback {
private DrawingThread _thread;
private Path path;
public DrawingPanel(Context context) {
super(context);
setDrawingCacheEnabled(true);
getHolder().addCallback(this);
_thread = new DrawingThread(getHolder(), this);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
synchronized (_thread.getSurfaceHolder()) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
path = new Path();
path.moveTo(event.getX(), event.getY());
path.lineTo(event.getX(), event.getY());
}else if(event.getAction() == MotionEvent.ACTION_MOVE){
path.lineTo(event.getX(), event.getY());
if(_graphics.size() > 0) {
_graphics.remove(_graphics.size() - 1);
}
_graphics.add(path);
}else if(event.getAction() == MotionEvent.ACTION_UP){
path.lineTo(event.getX(), event.getY());
_graphics.remove(_graphics.size() - 1);
_graphics.add(path);
_graphicsToSave.add(path);
}
return true;
}
}
#Override
public void onDraw(Canvas canvas) {
if (isFirstTime<3){
canvas.drawBitmap(myBitmap, 0, 0, null);
isFirstTime++;
}
for (Path path : _graphics) {
canvas.drawPath(path, mPaint);
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
_thread.setRunning(true);
_thread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
class DrawingThread extends Thread {
private SurfaceHolder _surfaceHolder;
private DrawingPanel _panel;
private boolean _run = false;
public DrawingThread(SurfaceHolder surfaceHolder, DrawingPanel panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
public SurfaceHolder getSurfaceHolder() {
return _surfaceHolder;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
if (c!=null)
_panel.onDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}
View mView;
mView.setDrawingCacheEnabled(true);
Bitmap newimg = mView.getDrawingCache();
Please get a bitmap and try saving that bitmap. Let me know you need more help
To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing).
Your current pasted code code shows that you are saving the myBitmap but it doesn't show whether you are setting the myBitmap as the bitmap for drawing or not. May be it's not the complete code.
The only reason i could think of for this problem is that you are not drawing on the bitmap that you are saving. Here is a link to the code I created for a finger paint. You can refer to this code to see how the bitmap is provided to the canvas and how path is drawn on the bitmap.