2016-04-20 4 views
0

Я хочу поместить водяной знак во все изображения, снятые моей камерой. Проблема в том, что размеры изображения различны для передней и задней камеры. Итак, водяной знак приходит разного размера. Как и в задней камере, водяной знак приближается немного меньше и на передней панели, так как размер изображения меньше, чем у задней камеры, водяной знак приближается немного больше. Как установить водяной знак на одинаковые размеры во всех картинах.Фиксация размера водяного знака во всех размерах изображения Android

Вот мой код:

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; 
     } 
    } 

Я попытался сделать picturesize же для передней и задней камеры, установив параметр равным PreviewSize. но это дает исключение времени выполнения, как размер недопустим:

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

ответ

1

В основном лучший способ для достижения этой цели является создание своего рода масштабирования алгоритма. Например, вы говорите, что хотите, чтобы водяной знак представлял 20 процентов ширины и 20 процентов высоты. Ну, если изображение 1000x1000, то вы узнаете, что водяной знак будет 200x200. Это будет масштабироваться для всех разных размеров изображения. Просто получите ширину и высоту изображения и установите процент ширины и высоты, которые вы хотите представить водяной знак.

Смежные вопросы