从矩形构造椭圆

时间:2017-02-01 15:00:32

标签: java image-processing shape ellipse

我制作的程序有点像Paint light,而且我已经达到了我希望用户能够选择椭圆区域的程度。我最初的想法是必须有某种方程允许我根据矩形的宽度和高度构造一个椭圆。但是,到目前为止,我还没有找到任何直截了当的东西。

这是我在用户拖动鼠标时选择矩形区域的代码(位于MouseAdapter内):

        @Override
        public void mouseDragged(MouseEvent e) {
               dragPoint = e.getPoint();
               if (selectionType.equalsIgnoreCase("Rectangle")) {
                int width = dragPoint.x - mouseAnchor.x;
                int height = dragPoint.y - mouseAnchor.y;
                subHeight = height;
                subWidth = width;
                int x = mouseAnchor.x;
                int y = mouseAnchor.y;

                if (width < 0) {
                    x = dragPoint.x;
                    width *= -1;
                }
                if (height < 0) {
                    y = dragPoint.y;
                    height *= -1;
                }
                selectionPane.setBounds(x, y, width, height);
                selectionPane.revalidate();
                repaint();
            }
  }

SelectionPane是扩展JPanel的自定义类的实例。我的想法是,我想从所选区域绘制一个填充椭圆,这样用户就可以看到他们所选择的内容。

这个计划的第二部分也是我遇到一些困惑的地方。在用户进行选择之后,我想使用所选区域作为指导将掩码应用于图像位。所以我也在使用字节数组。如何根据子图像的宽度,高度和原点查找计算椭圆中包含的字节?下面是我根据矩形选择得到子图像的代码(供参考):

        @Override
        public void mouseReleased(MouseEvent e) {
            if (subWidth != 0 && subHeight != 0) {
                try {
                    //numCols * (numRows - 1) + xPos
                    int startPos = img.getWidth() * (img.getHeight() - 1) + mouseAnchor.x;//the starting position for the total byte array of the original image. The mask will start here.
                    Main.setStartingPos(startPos);
                    Main.setSubImage(img.getSubimage(mouseAnchor.x, mouseAnchor.y, Math.abs(subWidth), Math.abs(subHeight)));
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    ImageIO.write(Main.getSubImage(), "bmp", baos);
                    Main.setImageRegion(baos.toByteArray()); //sets the region bytes in the Main class

                    Main.generateImageMask();//generates the mask after everything's been calculated. 
                } catch (IOException ex) {
                    Logger.getLogger(SelectionRectangle.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }

提前谢谢你。让我知道是否有任何方法可以让我的问题更清楚。

2 个答案:

答案 0 :(得分:1)

用于轴对齐椭圆使用参数方程(中心)

x = x0 + rx*cos(a)
y = y0 + ry*sin(a)


x0,y0是椭圆中心
rx,ry是半轴尺寸(矩形边的一半)
a是您想要获得的角度

该区域通常按角度间隔选择。角度通常由从中心(x0,y0)到实际鼠标位置(mx,my)或某个控制点的线确定为

ai = atan2(my-y0,mx-x0)

所以a = < a0,a1 > ai = { a0,a1 }是您的间隔角度。对于完整的椭圆a =< 0,2*M_PI> [rad]

这只是角度的圆近似,所以如果你想获得更精确的角度寻找

或应用圆/椭圆校正缩放...

答案 1 :(得分:1)

您可以从矩形中获取椭圆,如下所示:

Ellispe2D.Double el=new Ellispe2D.Double(x, y, width, height);

然后你可以按如下方式掩盖椭圆下面的位置:

Rectangle r=el.getBounds();
for(i=0; i<r.width; i++)
  for(j=0; j<r.height; j++)
    if(el.contains(r.x+i, r.y+j)) ... do whatever with this pixel add it to a list etc

-

对于像素r.x + i,r.y + j,您可以获取RGB并从中获取单个字节:

int pixel=image.getRGB(r.x+i, r.y+j);
int red=(pixel&0x00ff0000)>>16, green=(pixel&0x0000ff00)>>8, blue=pixel&0x000000ff;