2013-05-27 56 views
2

我有一个graphics.drawImage与我想绘制的中心缩放的缓冲区和一个带坐标和缩放比例的矩形我希望缓冲区被绘制为。Affinetransform中心比例坐标

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); 

的问题是什么,我需要做的就是它对齐到矩形的坐标?

缓冲区坐标应映射到矩形区域。

所以如果矩形的左上角为(30,80),我们需要的缩放后缓冲左上角是也(30,80)

的问题是,如果规模左上角前现在是(0,0),它取决于我们需要找到的比例(-15,10)。

+0

了'Buffer'如何定位在坐标网格数学?如果它的左上角位于原点上,那么我认为应该切换你的两个'translate'调用以使其回到那个位置。 – Arend

+0

这个问题一旦被缩小了角落的变化。 – adrix89

+0

你能提供一个例子吗?即为Buffer'和Rect'提供一组简单的坐标(使用变量的大写名称是令人困惑的!),然后指出哪些点应该映射到这个变换。 – MvG

回答

2

两点:

  • 在(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

编辑:

  • 重读的问题,我知道我错了什么你试图做:您正在绘制到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]] 
+0

是的,但问题是它并没有集中规模,这是我想要的,为什么这是一个问题开始,否则我可以使用drawimage规模。 – adrix89

+0

您的解决方案激发我寻找真正的解决方案。 – adrix89

+0

你意识到缩放向中心和缩放后翻译没有区别,对吧?这两个是相同的。 – maybeWeCouldStealAVan

0

解决方案是使用2个转换。

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); 

并使用tr绘图。

gfx.drawImage(buffer, tr, null); 

连接似乎保持AffineTransform分开,以便不会互相影响。

你或许可以使缩放锚任意如果您修改在tr.translate