兩點:
- 在(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:
![output](https://i.stack.imgur.com/A8PQp.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