如何通过itext在图像中心周围旋转? [英] How to rotate around the image center by itext?

查看:502
本文介绍了如何通过itext在图像中心周围旋转?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  double degPi = degrees * Math.PI / 180; 
double a = Math.cos(degPi)* tImgCover.getScaledHeight();
double b = Math.sin(degPi)* tImgCover.getScaledWidth();
double c = -Math.sin(degPi)* tImgCover.getScaledHeight();
double d = Math.cos(degPi)* tImgCover.getScaledWidth();
double e = absX;
double f = absY;

contentByte.addImage(imgae,a,b,c,d,e,f); / * add image * /

如何通过itext在图像中心周围旋转?

解决方案

如果我们有图片图片并且坐标 x,y ,我们可以在给定坐标的左下角不旋转地绘制图像,如下所示

  contentByte.addImage(image,image.getWidth(),0,0,image.getHeight(),x,y); 

来自资源的位图图像的大小为1x1,坐标原点位于其左下方。因此,此操作将图像拉伸到正确的大小并移动它,使其左下方位于给定的坐标处。



如果我们想要绘制相同的图像,就像上面绘制的一个围绕其中心旋转一个角度 rotate ,因此,我们可以通过移动1x1图像以使原点位于其中心,将其拉伸到其中心来实现正确的大小,旋转它,然后将原点(仍在旋转的图像的中心)移动到未旋转的图像的中心。使用 AffineTransform 实例(来自包 com.itextpdf.awt.geom )而不是数字tupels,这些操作更容易表达。因此:

  //绘制图像就像上一张图​​像围绕其中心旋转一样
//图像开始出现1x1,原点在左下方
//将原点移动到图像中心
AffineTransform A = AffineTransform.getTranslateInstance(-0.5,-0.5);
//将它拉伸到它的维度
AffineTransform B = AffineTransform.getScaleInstance(image.getWidth(),image.getHeight());
//旋转它
AffineTransform C = AffineTransform.getRotateInstance(rotate);
//将它移动到与上面相同的中心
AffineTransform D = AffineTransform.getTranslateInstance(x + image.getWidth()/ 2,y + image.getHeight()/ 2);
//连接
AffineTransform M =(AffineTransform)A.clone();
M.preConcatenate(B);
M.preConcatenate(C);
M.preConcatenate(D);
//绘制
contentByte.addImage(image,M);



使用翻转



OP在评论中询问


如何添加旋转和翻转图像?


为此你只需在上面的转换序列中插入一个镜像仿射变换。



不幸的是,OP没有提到他的意思是水平或垂直翻转。但是,因为改变旋转角度会相应地转换为另一个,这也不是必需的。

  //绘制图像好像前面的图像翻转并围绕其中心旋转
//图像开始为1x1,原点位于左下方
//将原点移动到图像中心
AffineTransform A = AffineTransform.getTranslateInstance (-0.5,-0.5);
//水平翻转
AffineTransform B =新的AffineTransform(-1,0,0,1,0,0);
//将它拉伸到它的维度
AffineTransform C = AffineTransform.getScaleInstance(image.getWidth(),image.getHeight());
//旋转它
AffineTransform D = AffineTransform.getRotateInstance(rotate);
//将它移动到与上面相同的中心
AffineTransform E = AffineTransform.getTranslateInstance(x + image.getWidth()/ 2,y + image.getHeight()/ 2);
//连接
AffineTransform M =(AffineTransform)A.clone();
M.preConcatenate(B);
M.preConcatenate(C);
M.preConcatenate(D);
M.preConcatenate(E);
//绘制
contentByte.addImage(image,M);



使用插值



OP询问另一个评论


抗锯齿如何?


iText Image 类知道 Interpolation 属性。通过将其设置为true(显然 将图像添加到文档之前),

  image。 setInterpolation(真); 

低分辨率图像在绘制时会进行插值。



例如使用具有不同颜色像素的2x2图像而不是Willi图像,您将得到以下结果,首先不进行插值,然后使用插值:





授予 AddRotatedImage.java test testAddRotatedInterpolatedImage 添加此项image:



小心: iText 图片属性插值有效地设置PDF图像字典中的插值条目。 PDF规范在此上下文中注明:


注意符合本标准的阅读器可能选择不实现PDF的此功能,或者可能使用任何特定的实现它所希望的插值。


因此,在某些观看者中,插值可能与您的观看者不同,甚至可能根本不同。如果您需要在每个查看器上进行特定类型的插值,请在将图像加载到iText 图像之前,使用所需的插值/消除锯齿量对图像进行升级。


double degPi = degrees * Math.PI / 180;   
double a = Math.cos(degPi)*tImgCover.getScaledHeight();
double b = Math.sin(degPi)*tImgCover.getScaledWidth();
double c = -Math.sin(degPi) * tImgCover.getScaledHeight();
double d = Math.cos(degPi)* tImgCover.getScaledWidth();
double e = absX;
double f = absY;

contentByte.addImage(imgae, a, b, c, d, e, f);/*add image*/

How to rotate around the image center by itext?

解决方案

If we have an Image image and coordinates x, y, we can draw the image without rotation with its lower left corner at the given coordinates like this

contentByte.addImage(image, image.getWidth(), 0, 0, image.getHeight(), x, y);

A bitmap image from the resources has a size of 1x1 with the coordinate origin at its lower left. Thus, this operation stretches the image to its correct size and moves it so its lower left is at the given coordinates.

If we want to draw the same image as if the one drawn above was rotated around its center by an angle rotate, therefore, we can do this by moving the 1x1 image so that the origin is in its center, stretch it to its correct size, rotate it, and then move the origin (which still is at the center of the rotated image) to the center of the unrotated image. These operations are easier to express using AffineTransform instances (from package com.itextpdf.awt.geom) instead number tupels. Thus:

// Draw image as if the previous image was rotated around its center
// Image starts out being 1x1 with origin in lower left
// Move origin to center of image
AffineTransform A = AffineTransform.getTranslateInstance(-0.5, -0.5);
// Stretch it to its dimensions
AffineTransform B = AffineTransform.getScaleInstance(image.getWidth(), image.getHeight());
// Rotate it
AffineTransform C = AffineTransform.getRotateInstance(rotate);
// Move it to have the same center as above
AffineTransform D = AffineTransform.getTranslateInstance(x + image.getWidth()/2, y + image.getHeight()/2);
// Concatenate
AffineTransform M = (AffineTransform) A.clone();
M.preConcatenate(B);
M.preConcatenate(C);
M.preConcatenate(D);
//Draw
contentByte.addImage(image, M);

(AddRotatedImage.java test method testAddRotatedImage)

For example drawing both images using

int x = 200;
int y = 300;
float rotate = (float) Math.PI / 3;

results in something like this:

With a Flip

The OP asked in a comment

how to add rotate and flip image?

For this you simply insert a mirroring affine transformation into the sequence of transformations above.

Unfortunately the OP did not mention which he meant a horizontal or a vertical flip. But as changing the rotation angle accordingly transforms one in the other, that isn't really necessary, either.

// Draw image as if the previous image was flipped and rotated around its center
// Image starts out being 1x1 with origin in lower left
// Move origin to center of image
AffineTransform A = AffineTransform.getTranslateInstance(-0.5, -0.5);
// Flip it horizontally
AffineTransform B = new AffineTransform(-1, 0, 0, 1, 0, 0);
// Stretch it to its dimensions
AffineTransform C = AffineTransform.getScaleInstance(image.getWidth(), image.getHeight());
// Rotate it
AffineTransform D = AffineTransform.getRotateInstance(rotate);
// Move it to have the same center as above
AffineTransform E = AffineTransform.getTranslateInstance(x + image.getWidth()/2, y + image.getHeight()/2);
// Concatenate
AffineTransform M = (AffineTransform) A.clone();
M.preConcatenate(B);
M.preConcatenate(C);
M.preConcatenate(D);
M.preConcatenate(E);
//Draw
contentByte.addImage(image, M);

(AddRotatedImage.java test method testAddRotatedFlippedImage)

The result with the same image as above:

With Interpolation

The OP asked in a yet another comment

How anti aliasing ?

The iText Image class knows an Interpolation property. By setting it to true (before adding the image to the document, obviously),

image.setInterpolation(true);

low resolution images are subject to interpolation when drawn.

E.g. using a 2x2 image with differently colored pixels instead of the image of Willi, you get the following results, first without interpolation, then with interpolation:

Confer the AddRotatedImage.java test testAddRotatedInterpolatedImage which adds this image:

Beware: iText Image property Interpolation effectively sets the Interpolate entry in the PDF image dictionary. The PDF specification notes in this context:

NOTE A conforming Reader may choose to not implement this feature of PDF, or may use any specific implementation of interpolation that it wishes.

Thus, on some viewers interpolation may occur differently than in your viewer, maybe even not at all. If you need a specific kind of interpolation on every viewer, upscale the image with the desired amount of interpolation / anti-aliasing before loading it into an iText Image.

这篇关于如何通过itext在图像中心周围旋转?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆