在所有图片尺寸Android中修复水印的大小

时间:2016-04-20 20:22:47

标签: android android-camera

我想在相机拍摄的所有图像中添加水印。问题是前后摄像头的图像尺寸不同。因此,水印的大小不同。就像在后置摄像头一样,水印变得更小,在前置摄像头,因为图像尺寸小于后置摄像头,水印会变得更大。如何在所有图片中将水印设置为相同大小。

这是我的代码:

    public class CameraActivity extends Activity implements Callback,
            OnClickListener {

        private SurfaceView surfaceView;
        private SurfaceHolder surfaceHolder;
        private Camera camera;
        private Button flipCamera;
        private Button flashCameraButton;
        private Button captureImage;
        private int cameraId;
        private boolean flashmode = false;
        private int rotation;
        public  static int i=0;
        ArrayList<File> captured_image;
        List<Camera.Size> mSupportedPreviewSizes;
       public static Camera.Size mPreviewSize;
        MeasureSize measureSize;
        public static Camera.Size size;
        public static int state=0;


        @Override
        protected void onResume() {
            super.onResume();

            i=0;
            captured_image.clear();
            captureImage.setVisibility(View.VISIBLE);


        }

        @Override
        protected void onPause() {
            super.onPause();
          releaseCamera();
        }

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.camera);
            // camera surface view created
            cameraId = CameraInfo.CAMERA_FACING_BACK;
            flipCamera = (Button) findViewById(R.id.flipCamera);
            flashCameraButton = (Button) findViewById(R.id.flash);
            captureImage = (Button) findViewById(R.id.captureImage);
            surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
            captured_image = new ArrayList<>();
            surfaceHolder = surfaceView.getHolder();
            surfaceHolder.addCallback(this);
            flipCamera.setOnClickListener(this);
            captureImage.setOnClickListener(this);
            flashCameraButton.setOnClickListener(this);

            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

            if (Camera.getNumberOfCameras() > 1) {
                flipCamera.setVisibility(View.VISIBLE);
            }
            if (!getBaseContext().getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_CAMERA_FLASH)) {
                flashCameraButton.setVisibility(View.GONE);
            }
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            if (!openCamera(CameraInfo.CAMERA_FACING_BACK)) {
                alertCameraDialog();
            }

        }
        private boolean openCamera(int id) {

            boolean result = false;
            cameraId = id;
            releaseCamera();
            try {
                camera = Camera.open(cameraId);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (camera != null) {
                try {
                    setUpCamera(camera);
                    camera.setErrorCallback(new ErrorCallback() {

                        @Override
                        public void onError(int error, Camera camera) {

                        }
                    });
                    camera.setPreviewDisplay(surfaceHolder);
                    camera.startPreview();
                    result = true;
                } catch (IOException e) {
                    e.printStackTrace();
                    result = false;
                    releaseCamera();
                }
            }
            return result;
        }

        private void setUpCamera(Camera c)
        {
            Camera.CameraInfo info = new Camera.CameraInfo();
            Camera.getCameraInfo(cameraId, info);

            rotation = getWindowManager().getDefaultDisplay().getRotation();
            int degree = 0;
            switch (rotation)
            {
                case Surface.ROTATION_0:
                    degree = 0;
                    break;
                case Surface.ROTATION_90:
                    degree = 90;
                    break;
                case Surface.ROTATION_180:
                    degree = 180;
                    break;
                case Surface.ROTATION_270:
                    degree = 270;
                    break;

                default:
                    break;
            }

            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
            {
                // frontFacing
                rotation = (info.orientation + degree) % 330;
                rotation = (360 - rotation) % 360;
            }
            else
            {
                // Back-facing
                rotation = (info.orientation - degree + 360) % 360;
            }
            c.setDisplayOrientation(rotation);

            mSupportedPreviewSizes = c.getParameters().getSupportedPreviewSizes();


            Camera.Parameters parameters = c.getParameters();



            measureSize = new MeasureSize(this);

            parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
            if (parameters.getSupportedFocusModes().contains(
                    Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
            {
                parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);

            }


            List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
            size = sizes.get(0);

                 for (int i = 0; i < sizes.size(); i++) {
                 if (sizes.get(i).width > size.width) {
                        size = sizes.get(i);

                    }

                }

                parameters.setPictureSize(size.width, size.height);

            }


            c.setParameters(parameters);


            Parameters params = c.getParameters();

            showFlashButton(params);

            List<String> focusModes = params.getSupportedFlashModes();
            if (focusModes != null)
            {
                if (focusModes
                        .contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
                    params.setFlashMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                }
            }

            params.setRotation(rotation);
        }


        private void showFlashButton(Parameters params) {
            boolean showFlash = (getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_CAMERA_FLASH) && params.getFlashMode() != null)
                    && params.getSupportedFlashModes() != null
                    && params.getSupportedFocusModes().size() > 1;

            flashCameraButton.setVisibility(showFlash ? View.VISIBLE
                    : View.INVISIBLE);

        }

        private void releaseCamera() {
            try {
                if (camera != null) {
                    camera.setPreviewCallback(null);
                    camera.setErrorCallback(null);
                    camera.stopPreview();
                    camera.release();
                    camera = null;
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.e("error", e.toString());
                camera = null;
            } 
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                                   int height)
        {
            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.Parameters parameters = camera.getParameters();


                camera.setDisplayOrientation(90);
                camera.setPreviewDisplay(surfaceHolder);
                camera.startPreview();

            } catch (Exception e){
                Log.d("Activity", "Error starting camera preview: " + e.getMessage());
            }
        }


        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {

        }

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.flash:
                    flashOnButton();
                    break;
                case R.id.flipCamera:
                    flipCamera();
                    break;
                case R.id.captureImage:
                    takeImage();
                    break;

                default:
                    break;
            }
        }

        private void takeImage() {
            camera.takePicture(null, null, new PictureCallback() {

                private File imageFile;

                @Override
                public void onPictureTaken(byte[] data, Camera camera) {

                    try {
                        // convert byte array into bitmap
                        Bitmap loadedImage = null;
                        Bitmap rotatedBitmap = null;
                        loadedImage = BitmapFactory.decodeByteArray(data, 0,
                                data.length);
                         Log.e("Activity", "IMAGE " + data.length);
                        // rotate Image

                        Matrix rotateMatrix = new Matrix();
                        rotateMatrix.postRotate(rotation);
                        rotatedBitmap = Bitmap.createBitmap(loadedImage, 0, 0,
                                loadedImage.getWidth(), loadedImage.getHeight(),
                                rotateMatrix, false);



                            int w = rotatedBitmap.getWidth();
                            int h = rotatedBitmap.getHeight();
                         //cropped bitmap


                            Bitmap result = Bitmap.createBitmap(w, h, rotatedBitmap.getConfig());
                            Canvas canvas = new Canvas(result);
                            canvas.drawBitmap(rotatedBitmap, 0, 0, null);
                     Bitmap waterMark = BitmapFactory.decodeResource(getResources(), R.drawable.watermark2);
                      float hh = waterMark.getHeight();
                      float ww = waterMark.getWidth();
                     canvas.drawBitmap(waterMark, w - ww, h - hh, null);
                String state = Environment.getExternalStorageState();
                        File folder = null;
                        if (state.contains(Environment.MEDIA_MOUNTED)) {
                            folder = new File(Environment
                                    .getExternalStorageDirectory() + "/Pictures");
                        } else {
                            folder = new File(Environment
                                    .getExternalStorageDirectory() + "/Pictures");
                        }

                        boolean success = true;
                        if (!folder.exists()) {
                            success = folder.mkdirs();
                        }
                        if (success) {
                            java.util.Date date = new java.util.Date();
                            imageFile = new File(folder.getAbsolutePath()
                                    + File.separator
                                    + new Timestamp(date.getTime()).toString()
                                    + "Image.jpg");

                            imageFile.createNewFile();
                        } else {
                            Toast.makeText(getBaseContext(), "Image Not saved",
                                    Toast.LENGTH_SHORT).show();
                            return;
                        }

                        ByteArrayOutputStream ostream = new ByteArrayOutputStream();

                        // save image into gallery
                        result.compress(CompressFormat.JPEG, 100, ostream);

                        FileOutputStream fout = new FileOutputStream(imageFile);
                        fout.write(ostream.toByteArray());
                        fout.close();
                        captured_image.add(imageFile);
                        ContentValues values = new ContentValues();

                        values.put(Images.Media.DATE_TAKEN,
                                System.currentTimeMillis());
                        values.put(Images.Media.MIME_TYPE, "image/jpeg");
                        values.put(MediaStore.MediaColumns.DATA,
                                imageFile.getAbsolutePath());

                        CameraActivity.this.getContentResolver().insert(
                                Images.Media.EXTERNAL_CONTENT_URI, values);


                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    finally {

                        i++;
                        if(i<5) {
                            if(i>2) {
                                camera.startPreview();
                                creategif.setVisibility(View.VISIBLE);
                            }
                            else
                            {

                                camera.startPreview();

                            }
                        }

                        else
                        {
                            captureImage.setVisibility(View.INVISIBLE);
                            Toast.makeText(CameraActivity.this,"You can't take more than 5 pictures", Toast.LENGTH_LONG).show();
                        }

                    }

                }
            });
        }

        private void flipCamera() {
            int id = (cameraId == CameraInfo.CAMERA_FACING_BACK ? CameraInfo.CAMERA_FACING_FRONT
                    : CameraInfo.CAMERA_FACING_BACK);
            if (!openCamera(id)) {
                alertCameraDialog();
            }
        }

        private void alertCameraDialog() {
            AlertDialog.Builder dialog = createAlert(CameraActivity.this,
                    "Camera info", "error to open camera");
            dialog.setNegativeButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();

                }
            });

            dialog.show();
        }

        private Builder createAlert(Context context, String title, String message) {

            AlertDialog.Builder dialog = new AlertDialog.Builder(
                    new ContextThemeWrapper(context,
                            android.R.style.Theme_Holo_Light_Dialog));
          //  dialog.setIcon(R.drawable.ic_launcher);
            if (title != null)
                dialog.setTitle(title);
            else
                dialog.setTitle("Information");
            dialog.setMessage(message);
            dialog.setCancelable(false);
            return dialog;

        }

        private void flashOnButton() {
            if (camera != null) {
                try {
                    Parameters param = camera.getParameters();
                    param.setFlashMode(!flashmode ? Parameters.FLASH_MODE_TORCH
                            : Parameters.FLASH_MODE_OFF);
                    camera.setParameters(param);
                    flashmode = !flashmode;
                } catch (Exception e) {
                    // TODO: handle exception
                }

            }
        }

       public void gallery(View v)
       {
           Intent i = new Intent(CameraActivity.this, GIFGallery.class);
           i.putExtra("arraylist", captured_image);
           startActivity(i);
       }
        public void reset_gallery(View v)
        {
                  i=0;
            captured_image.clear();

               captureImage.setVisibility(View.VISIBLE);

                camera.startPreview();

        }

        public class MeasureSize extends View {
            public MeasureSize(Context context) {
                super(context);

                measure(surfaceView.getWidth(), surfaceView.getHeight());
            }




            @Override
            protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {

                if (mSupportedPreviewSizes != null) {
                    mPreviewSize =  getOptimalPreviewSize(mSupportedPreviewSizes, surfaceView.getWidth(), surfaceView.getHeight());
                }
            }
        }



        private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
            final double ASPECT_TOLERANCE = 0.1;
            double targetRatio=(double)h / w;
            if (sizes == null) return null;
            Camera.Size optimalSize = null;
            double minDiff = Double.MAX_VALUE;
            int targetHeight = h;
            for (Camera.Size size : sizes) {
                double ratio = (double)  size.width / size.height;
                if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }

            if (optimalSize == null) {
                minDiff = Double.MAX_VALUE;
                for (Camera.Size size : sizes) {
                    if (Math.abs(size.height - targetHeight) < minDiff) {
                        optimalSize = size;
                        minDiff = Math.abs(size.height - targetHeight);
                    }
                }
            }
            Log.e("Activity", "OPTIMAL SIZE " + optimalSize);
            return optimalSize;
        }
    }

我尝试通过将参数设置为previewSize来使前后摄像头的图像尺寸相同。但由于大小无效,它会给出运行时异常:

parameters.setPictureSize(mPreviewSize.width, mPreviewSize.height);

1 个答案:

答案 0 :(得分:1)

基本上,实现这一目标的最佳方法是创建某种缩放算法。例如,您说您希望水印代表宽度的20%和高度的20%。好吧,如果图像是1000x1000那么你会知道水印将是200x200。这将适用于所有不同的图像尺寸。只需获取图像的宽度和高度,并设置希望水印表示的宽度和高度的百分比。