我正在编写一个程序,我正在拍照,然后想要将图片存储到SD卡中,最后尝试调整现有图像的大小(然后用旧图像重写).
我的代码几乎可以在所有设备上正常工作,但仅在三星设备上遇到此问题.
当我捕捉图像时,我无法将图像存储到SD卡中
logcat的:
12-05 18:23:15.407: E/AndroidRuntime(2378): FATAL EXCEPTION: main 12-05 18:23:15.407: E/AndroidRuntime(2378): java.lang.NullPointerException 12-05 18:23:15.407: E/AndroidRuntime(2378): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:461) 12-05 18:23:15.407: E/AndroidRuntime(2378): at com.example.kdh.TakePhotoActivity$1.onPictureTaken(TakePhotoActivity.java:325) 12-05 18:23:15.407: E/AndroidRuntime(2378): at android.hardware.Camera$EventHandler.handleMessage(Camera.java:789) 12-05 18:23:15.407: E/AndroidRuntime(2378): at android.os.Handler.dispatchMessage(Handler.java:99) 12-05 18:23:15.407: E/AndroidRuntime(2378): at android.os.Looper.loop(Looper.java:137) 12-05 18:23:15.407: E/AndroidRuntime(2378): at android.app.ActivityThread.main(ActivityThread.java:4921) 12-05 18:23:15.407: E/AndroidRuntime(2378): at java.lang.reflect.Method.invokeNative(Native Method) 12-05 18:23:15.407: E/AndroidRuntime(2378): at java.lang.reflect.Method.invoke(Method.java:511) 12-05 18:23:15.407: E/AndroidRuntime(2378): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1036) 12-05 18:23:15.407: E/AndroidRuntime(2378): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:803) 12-05 18:23:15.407: E/AndroidRuntime(2378): at dalvik.system.NativeStart.main(Native Method)
码:
private void createCamera() { // Create an instance of Camera mCamera = getCameraInstance(); // Setting the right parameters in the camera Camera.Parameters params = mCamera.getParameters(); ListallSizes = params.getSupportedPictureSizes(); Camera.Size size = allSizes.get(0); // get top size for (int i = 0; i < allSizes.size(); i++) { if (allSizes.get(i).width > size.width) size = allSizes.get(i); } //set max Picture Size params.setPictureSize(size.width, size.height); params.setPictureFormat(PixelFormat.JPEG); params.setJpegQuality(85); mCamera.setParameters(params); // Create our Preview view and set it as the content of our activity. mPreview = new CameraPreview(TakePhotoActivity.this, mCamera); FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); // Calculating the width of the preview so it is proportional. float widthFloat = (float) (deviceHeight) * 4 / 3; int width = Math.round(widthFloat); // Resizing the LinearLayout so we can make a proportional preview. This // approach is not 100% perfect because on devices with a really small // screen the the image will still be distorted - there is place for // improvment. RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width, deviceHeight); preview.setLayoutParams(layoutParams); // Adding the camera preview after the FrameLayout and before the button // as a separated element. preview.addView(mPreview, 0); } @Override protected void onResume() { super.onResume(); // Test if there is a camera on the device and if the SD card is // mounted. if (!checkCameraHardware(this)) { finish(); } else if (!checkSDCard()) { finish(); } // Creating the camera createCamera(); // Register this class as a listener for the accelerometer sensor sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { super.onPause(); // release the camera immediately on pause event releaseCamera(); // removing the inserted view - so when we come back to the app we // won't have the views on top of each other. preview.removeViewAt(0); } private void releaseCamera() { if (mCamera != null) { mCamera.stopPreview(); mCamera.setPreviewCallback(null); mCamera.release(); // release the camera for other applications mCamera = null; } } /** Check if this device has a camera */ private boolean checkCameraHardware(Context context) { if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) { // this device has a camera return true; } else { // no camera on this device return false; } } private boolean checkSDCard() { boolean state = false; String sd = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(sd)) { state = true; } return state; } /** * A safe way to get an instance of the Camera object. */ public static Camera getCameraInstance() { Camera c = null; try { // attempt to get a Camera instance c = Camera.open(); } catch (Exception e) { // Camera is not available (in use or does not exist) } // returns null if camera is unavailable return c; } private PictureCallback mPicture = new PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { // Replacing the button after a photho was taken. linearLayout1.setVisibility(View.GONE); linearLayout2.setVisibility(View.VISIBLE); File directory = new File(Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_PICTURES) +"/Data/" + stringFolderName); fileName = String.format("%d.jpg", System.currentTimeMillis()); File outFile = new File(directory, fileName); try { FileOutputStream purge = new FileOutputStream(outFile); purge.write(data); purge.close(); } catch (FileNotFoundException e) { Log.d("DG_DEBUG", "File not found: " + e.getMessage()); } catch (IOException e) { Log.d("DG_DEBUG", "Error accessing file: " + e.getMessage()); } String cPath = Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_PICTURES) +"/Data/" + stringFolderName + "/"+ fileName; Bitmap bMap= BitmapFactory.decodeFile(cPath); Bitmap out = Bitmap.createScaledBitmap(bMap, 1024, 768, true); //Bitmap adjustedBitmap = Bitmap.createBitmap(out, 0, 0, 1024, 768, matrix, true); Log.d("image-name:-", fileName); File resizedFile = new File(directory, fileName); OutputStream fOut=null; try { fOut = new BufferedOutputStream(new FileOutputStream(resizedFile)); out.compress(Bitmap.CompressFormat.JPEG, 85, fOut); fOut.flush(); fOut.close(); bMap.recycle(); out.recycle(); } catch (Exception e) { // TODO } // Adding Exif data for the orientation. For some strange reason the // ExifInterface class takes a string instead of a file. try { exif = new ExifInterface(directory + "/"+fileName); exif.setAttribute(ExifInterface.TAG_ORIENTATION, "" + orientation); exif.saveAttributes(); } catch (IOException e) { e.printStackTrace(); } } };
Muhammad Uma.. 7
尝试此代码并尝试在后台线程而不是UI中保存图像或视频
private PictureCallback mPicture = new PictureCallback() { @Override public void onPictureTaken(final byte[] data, Camera camera) { final File pictureFile = getOutputMediaFile(); if (pictureFile == null) { return; } Thread thread = new Thread() { @Override public void run() { try { FileOutputStream fos = new FileOutputStream(pictureFile); fos.write(data); fos.close(); } catch (Exception e) { e.printStackTrace(); } } }; thread.start(); } }; private File getOutputMediaFile() { File mediaStorageDir = new File( Environment.getExternalStorageDirectory(), "/Images"); if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { Log.d("Camera", "failed to create directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss") .format(new Date()); File mediaFile; String image_path = mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"; mediaFile = new File(image_path); return mediaFile; }
小智.. 6
未创建数据时.您无法使用位图.
这意味着需要一点时间来创建image.so bitmapcreate返回null.
我认为PictureCallback像Thread一样运行
解决此问题.更改此代码
Bitmap bMap= BitmapFactory.decodeFile(cPath); Bitmap out = Bitmap.createScaledBitmap(bMap, 1024, 768, true);
至
Bitmap bMap = BitmapFactory.decodeByteArray(data, 0,.length); Bitmap out = Bitmap.createScaledBitmap(bMap, 1024, 768, true);
该代码将byte []转换为位图(参见picturecallback中的数据);
相机API参考:相机API教程
尝试此代码并尝试在后台线程而不是UI中保存图像或视频
private PictureCallback mPicture = new PictureCallback() { @Override public void onPictureTaken(final byte[] data, Camera camera) { final File pictureFile = getOutputMediaFile(); if (pictureFile == null) { return; } Thread thread = new Thread() { @Override public void run() { try { FileOutputStream fos = new FileOutputStream(pictureFile); fos.write(data); fos.close(); } catch (Exception e) { e.printStackTrace(); } } }; thread.start(); } }; private File getOutputMediaFile() { File mediaStorageDir = new File( Environment.getExternalStorageDirectory(), "/Images"); if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { Log.d("Camera", "failed to create directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss") .format(new Date()); File mediaFile; String image_path = mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"; mediaFile = new File(image_path); return mediaFile; }
未创建数据时.您无法使用位图.
这意味着需要一点时间来创建image.so bitmapcreate返回null.
我认为PictureCallback像Thread一样运行
解决此问题.更改此代码
Bitmap bMap= BitmapFactory.decodeFile(cPath); Bitmap out = Bitmap.createScaledBitmap(bMap, 1024, 768, true);
至
Bitmap bMap = BitmapFactory.decodeByteArray(data, 0,.length); Bitmap out = Bitmap.createScaledBitmap(bMap, 1024, 768, true);
该代码将byte []转换为位图(参见picturecallback中的数据);
相机API参考:相机API教程