两点:
- 在(0,0)一
BufferedImage
开始的左上角,这简化了操作。
- 当您将操作添加到
AffineTransform
时,它会将其放入队列的前面。 (我知道没有真正的队列,请参阅下面的内容。)如果您添加翻译,然后添加比例,然后过滤数据,您的数据看起来好像经过了过滤,然后翻译了。
如果你想在矩阵,它应该是这样的:
AffineTransform at = new AffineTransform();
你现在有一个空的单位矩阵(无操作):
[A0] = [I]
at.translate(x, y);
现在你已经添加了一个翻译:
[A1] = [I] [ TR] = [TR]
at.scale(x, y);
然后一个规模:
[A2] = [A0] [SC] = [TR] [SC]
所以,当您筛选数据(点是列)你:
[新] = [A2] [老] = [TR] [SC] [老] = [TR] [scaledVersion]
下面是一个例子:
static String backgroundFilename = "green.png";
static String foregroundFilename = "red.png";
public static void drawImageInRectangle(BufferedImage src, BufferedImage dst, Rectangle rect) {
if (dst == src) {
src = new BufferedImage(src.getColorModel(), src.copyData(null), src.getColorModel().isAlphaPremultiplied(), null);
}
AffineTransform at = new AffineTransform();
// AffineTransform applies transformations in the OPPOSITE ORDER to how they were added
at.translate(rect.x, rect.y);
at.scale((double)rect.width/src.getWidth(), (double)rect.height/src.getHeight());
AffineTransformOp op = new AffineTransformOp(at, new RenderingHints(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC));
op.filter(src, dst);
}
static Rectangle getCenterRectangle(BufferedImage image) {
int w = image.getWidth();
int h = image.getHeight();
return new Rectangle(w/4, h/4, w/2, h/2);
}
public static void main(String[] args) throws Exception {
BufferedImage background = ImageIO.read(new File(backgroundFilename));
BufferedImage foreground = ImageIO.read(new File(foregroundFilename));
drawImageInRectangle(foreground, background, getCenterRectangle(background));
ImageIO.write(background, "png", new File("output.png"));
}
output.png:
编辑:
- 重读的问题,我知道我错了什么你试图做:您正在绘制到
Graphics2D
,而不是另一个BufferedImage
。抱歉。最简单的解决方案就是使用Graphics2D.drawImage
并指定目标矩形。请务必先登录setRenderingHint
。
- 只要合适的翻译是在词后完成的,缩放东西的原点在哪里并不重要。如果你怀疑它们是相同的,切记
AffineTransform
仅有6个double
值列表,并尝试这个 public static AffineTransform longWay(BufferedImage buffer, Rectangle rect){
AffineTransform tr= new AffineTransform();
AffineTransform tr2= new AffineTransform();
tr.translate(
rect.x+(rect.width-buffer.getWidth())/2,
rect.y+(rect.height-buffer.getHeight())/2);
tr2.translate(buffer.getWidth()/2, buffer.getHeight()/2);
tr2.scale(
(double)rect.width/buffer.getWidth(),
(double)rect.height/buffer.getHeight());
tr2.translate(-buffer.getWidth()/2,-buffer.getHeight()/2);
tr.concatenate(tr2);
return tr;
}
public static AffineTransform shortWay(BufferedImage buffer, Rectangle rect){
AffineTransform tr = new AffineTransform();
tr.translate(rect.x, rect.y);
tr.scale((double)rect.width/buffer.getWidth(), (double)rect.height/buffer.getHeight());
return tr;
}
:
考虑这两个相当于功能
System.out.println(longWay(buff,rect));
System.out.println(shortWay(buff,rect));
输出:
AffineTransform[[0.5, 0.0, 32.0], [0.0, 0.5, 24.0]]
AffineTransform[[0.5, 0.0, 32.0], [0.0, 0.5, 24.0]]
了'Buffer'如何定位在坐标网格数学?如果它的左上角位于原点上,那么我认为应该切换你的两个'translate'调用以使其回到那个位置。 – Arend
这个问题一旦被缩小了角落的变化。 – adrix89
你能提供一个例子吗?即为Buffer'和Rect'提供一组简单的坐标(使用变量的大写名称是令人困惑的!),然后指出哪些点应该映射到这个变换。 – MvG