title: Android: OpenCV image gets cropped after rotation in between -75 to -105 and 75 to 105
body: <p>I am trying to put a watermark/Image on another image, we can zoom in, zoom out, drag and rotate the watermark image by fingertouch. I am using Open CV library to rotate the image as suggested in this post 
  <a href="https://stackoverflow.com/questions/12852578/image-rotation-with-opencv-in-android-cuts-off-the-edges-of-an-image#_=_">image rotation with opencv in android cuts off the edges of an image</a></p>
  
  <p>It works fine until the rotation angle gets in between -75 to -105 and 75 to 105. In this range my image get cropped or it changes its position. I have tried several ways to get the right center point for the watermark image to put it in right position after rotating it but failed to do so. </p>
  
  <p>Here is the code to rotate the image    </p>
  
  <pre><code>// CALCULATE ROTATED WATERMARK IMAGE
      private void CreateRotatedWaterMark() 
      {
          // Means rotation took place
          if (waterMarkAngle &gt; 0 || waterMarkAngle &lt; 0) {
              // calculation for new width/height of rotated watermark image
              newWidthHeight = boundingWaterMarkRect();
  
              // remove when done testing
              double pivotX = newWidthHeight[0] / 2; // 0 is width
              double pivotY = newWidthHeight[1] / 2; // 1 is height
  
              // rotating water image
              org.opencv.core.Point center;
              Size targetSize;
              Mat targetMat;
  
              // scalar is color/ RGBA , but alpha doesn't seem to work
              Scalar colorScalar = new Scalar(255, 190, 190, 0);
              double offsetX = (newWidthHeight[0] - scaledImage.width()) / 2;
              double offsetY = (newWidthHeight[1] - scaledImage.height()) / 2;
  
              // watermark's rotation lays somewhere in between 75' AND 105' OR
              // -75' AND -105'
              Log.e(TAG, "check =&gt; offsetX/offsetY Before  =&gt; " + offsetX + " / "
                      + offsetY);
              if (offsetX &lt; 0 || offsetY &lt; 0) {
                  //this gets true when angle of rotation gets between -75 to -105 and 75 to 105
                  // change the offsets, now new newWidth &lt; oldWidth AND newHeight
                  // &gt; oldHeight (could be vice versa)
                  offsetX = (newWidthHeight[0] - scaledImage.height()) / 2;
                  offsetY = (newWidthHeight[1] - scaledImage.width()) / 2;
                  // Declaring new target size and target Mat, so rotated image is
                  // placed in new target Mat
                  targetSize = new Size(newWidthHeight[1], newWidthHeight[0]);
                  targetMat = new Mat(targetSize, scaledImage.type(), colorScalar);
  
                  // Getting the reference of center area from target Mat,
                  // below we're copying the actual image (scaledImage) to center
                  // position to target Mat
                  Mat waterSubmat = targetMat.submat((int) offsetX, (int) offsetX
                          + scaledImage.height(), (int) offsetY, (int) offsetY
                          + scaledImage.width());
                  scaledImage.copyTo(waterSubmat);
  
                  // Writing target image to sdcard, so we can know if its working
                  // properly, remove it when done with testing
                  Highgui.imwrite("mnt/sdcard/scaled90.png", targetMat);
                  Highgui.imwrite("mnt/sdcard/waterSubmat.png", waterSubmat);
                  Highgui.imwrite("mnt/sdcard/ScaledImage.png", scaledImage);
  
                  // targetSize is reverted again, so that target mat is pasted on
                  // canvas image
                  targetSize = new Size(newWidthHeight[0], newWidthHeight[1]);
  
                  pivotX = newWidthHeight[0] / 2;
                  pivotY = newWidthHeight[1] / 2;
                  Log.e(TAG, "check =&gt; pivotX/pivotY =&gt; " + pivotX + " / "
                          + pivotY);
                  Log.e(TAG, "check =&gt; Angle =&gt; " + waterMarkAngle);
                  center = new org.opencv.core.Point(pivotX, pivotY);
              } else {
                  center = new org.opencv.core.Point(pivotX, pivotY);
                  targetSize = new Size(newWidthHeight[0], newWidthHeight[1]);
  
                  targetMat = new Mat(targetSize, scaledImage.type(), colorScalar);
  
                  // Centralizing watermark
                  Mat waterSubmat = targetMat.submat((int) offsetY, (int) offsetY
                          + scaledImage.height(), (int) offsetX, (int) offsetX
                          + scaledImage.width());
                  scaledImage.copyTo(waterSubmat);
                  Highgui.imwrite("mnt/sdcard/scaled10.png", targetMat);
  
              }
              Mat rotImage = Imgproc.getRotationMatrix2D(center, waterMarkAngle,
                      1.0); // 1.0 means scale 100%
              Highgui.imwrite("mnt/sdcard/Rotated90.png", rotImage);
              // Mat waterSubmat1 = rotImage.submat(0, scaledImage.height(), 0,
              // scaledImage.width());
              Mat resultMat = new Mat();
              // scalar for color, Imagproc.warAffine actually rotates the final
              // watermark on canvas image
              colorScalar = new Scalar(122, 22, 22);
              Imgproc.warpAffine(targetMat, resultMat, rotImage, targetSize,
                      Imgproc.INTER_LINEAR, Imgproc.BORDER_CONSTANT, colorScalar);
              Log.i(TAG, "check MATRIX =  " + resultMat.toString());
              Log.i(TAG, "check Result Mat " + resultMat.size().toString());
              scaledImage = resultMat.clone();
              Highgui.imwrite("mnt/sdcard/Result100.png", targetMat);
  
              // Log.i(TAG, "check Result postion  =  "+ resultMat.r);
              // WRITE SOME TEXT ON CANVAS IMAGE, its not rotated
              Core.putText(scaledImage, "angle: " + waterMarkAngle,
                      new org.opencv.core.Point(0, scaledImage.height() / 2),
                      Core.FONT_HERSHEY_TRIPLEX, 2, new Scalar(23, 12, 450, 0.5),
                      2); // CV_BLUR_NO_SCALE
  
          } else {
              // CHANGE OPACITY OF WATERMARK IMAGE
              // Core.multiply(scaledImage, new Scalar(1, 1, 1, 0.6),
              // scaledImage);
  
              // REMOVE THIS WHEN DONE TESTING
              // Highgui.imwrite("mnt/sdcard/opacityWatermark.png",scaledImage);
          }
      }
  
  private double[] boundingWaterMarkRect() {
  
      // -----NEW CALCULATION------
  
      // so we always get positive angle
      double tempAngle = ((waterMarkAngle &lt; 0 ? 360 - waterMarkAngle : waterMarkAngle) % 360);
      double radians = Math.toRadians(tempAngle);
  
      Log.i(TAG, "check =&gt; radian =&gt; "+ radians);
  
      double sin = Math.abs(Math.sin(radians));
      double cos = Math.abs(Math.cos(radians));
  
      double newWidth = (double) (scaledImage.width() * cos + scaledImage.height() * sin);
      double newHeight = (double) (scaledImage.width() * sin + scaledImage.height() * cos);
      double[] wh = {newWidth, newHeight};
  
      return wh;
  }
  </code></pre>
  
  <p>Following are two images first one is right and the other is rotated wrong</p>
  
  <p><img src="https://i.stack.imgur.com/2spyG.png" alt="Right Rotated"></p>
  
  <p><img src="https://i.stack.imgur.com/Rmd5q.png" alt="Wrong/Cropped Rotated"></p>
  
  <p>Anyone have got solution for it?</p>