1

У меня есть изображение, и я должен повернуть его на 45, 90, 135, 180 градусов. Что я делаю:AffineTransform усекает изображение

try { 
    BufferedImage src = ImageIO.read(new File("src.png")); 
    double ang = Math.toRadians(90); 

    AffineTransform t = new AffineTransform(); 
    t.setToRotation(ang, src.getWidth()/2, src.getHeight()/2); 

    AffineTransformOp op = new AffineTransformOp(t, null); 
    BufferedImage dst = new BufferedImage(src.getWidth(), src.getHeight(), src.getType()); 
    op.filter(src, dst); 

    ImageIO.write(dst, "png", new File("output.png")); 
} catch(Exception ex) { ex.printStackTrace(); 
} 

Проблема заключается в том, что изображение меняет свое положение и выходит из пределов конечного изображения:

The problem http://img32.imageshack.us/img32/3328/resultcs.png

Я гугле это и нашел решение в этом вопросе : AffineTransform truncates image, what do I wrong? Но я совершенно не понимаю, и это работает только для квадрантов. Я пытался умножить в два раза ширину и высоту назначения, но это не удалось:

Another fail http://img401.imageshack.us/img401/2417/result2a.png

Как это исправить? На целевом изображении не должно быть никаких дополнительных (за исключением необходимости для диагонального вращения) пробелов или усеченной области. Угловые проблемы (0 == 180 или по часовой стрелке) не важны.

Спасибо за любую помощь.

+0

Как насчет дополнительного пространства по диагонали на 45 и 135? Должна быть прозрачной? 180 идентично 0? Пожалуйста, отредактируйте свой вопрос, чтобы включить [sscce] (http://sscce.org/), который показывает проблему, которую вы описываете. ['FauxImage'] (http://stackoverflow.com/a/8090328/230513) может быть удобным дополнением. – trashgod

+0

У меня есть пример и фотографии, которые иллюстрируют проблему. Код готов к запуску. – Cenius

ответ

4

Редактировать: теперь это работает для общего случая.

Вращение выполняется по центру, а центр размещается в том же положении на целевом изображении, что и в исходном изображении (правильное поведение).

Я изменил свой код, чтобы преобразовать прямоугольник исходного изображения, чтобы мы могли легко получить новые размеры/смещение изображения. Это используется для создания адресата BufferedImage правильных размеров и добавления перевода к вашему AffineTransform, чтобы центр изображения располагался в центре целевого изображения.

 BufferedImage src = ImageIO.read(new File(INPUT)); 
     int w = src.getWidth(); 
     int h = src.getHeight(); 

     AffineTransform t = new AffineTransform(); 
     double ang = Math.toRadians(35); 
     t.setToRotation(ang, w/2d, h/2d); 

     // source image rectangle 
     Point[] points = { 
      new Point(0, 0), 
      new Point(w, 0), 
      new Point(w, h), 
      new Point(0, h) 
     }; 

     // transform to destination rectangle 
     t.transform(points, 0, points, 0, 4); 

     // get destination rectangle bounding box 
     Point min = new Point(points[0]); 
     Point max = new Point(points[0]); 
     for (int i = 1, n = points.length; i < n; i ++) { 
      Point p = points[i]; 
      double pX = p.getX(), pY = p.getY(); 

      // update min/max x 
      if (pX < min.getX()) min.setLocation(pX, min.getY()); 
      if (pX > max.getX()) max.setLocation(pX, max.getY()); 

      // update min/max y 
      if (pY < min.getY()) min.setLocation(min.getX(), pY); 
      if (pY > max.getY()) max.setLocation(max.getX(), pY); 
     } 

     // determine new width, height 
     w = (int) (max.getX() - min.getX()); 
     h = (int) (max.getY() - min.getY()); 

     // determine required translation 
     double tx = min.getX(); 
     double ty = min.getY(); 

     // append required translation 
     AffineTransform translation = new AffineTransform(); 
     translation.translate(-tx, -ty); 
     t.preConcatenate(translation); 

     AffineTransformOp op = new AffineTransformOp(t, null); 
     BufferedImage dst = new BufferedImage(w, h, src.getType()); 
     op.filter(src, dst); 

     ImageIO.write(dst, "png", new File(OUTPUT)); 
+0

Любой шанс, что вы будете работать в [SSCCE] (http://sscce.org/)? Есть несколько [изображений на моем сайте] (http://pscode.org/media/#image), к которым вы можете подключиться к исходному изображению. –

0

Я предлагаю заменить

AffineTransformOp op = new AffineTransformOp(t, null); 

с

AffineTransformOp op = new AffineTransformOp(t, AffineTransformOp.TYPE_BILINEAR); 

Это улучшит намного качество продукции.

+0

Пожалуйста, прямо укажите, какая строка по содержанию ... – Kukeltje

+0

Это не дает ответа на вопрос. Чтобы критиковать или запросить разъяснения у автора, оставьте комментарий ниже своего сообщения - вы всегда можете прокомментировать свои собственные сообщения, и как только у вас будет достаточно [репутации] (http://stackoverflow.com/help/whats-reputation), вы будете быть в состоянии [прокомментировать любое сообщение] (http://stackoverflow.com/help/privileges/comment). - [Из обзора] (/ review/low-quality-posts/11272967) –

+0

@MuhammedRefaat Как это не пытается дать ответ? Это может быть совершенно неправильно [но это не значит, что мы должны злоупотреблять очередями обзора, чтобы удалить его.] (Http: //meta.stackoverflow.com/q/287563/1849664) – Undo

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