2012-05-31 2 views
3

У меня есть класс, который рисует форму из png-изображения, так что я могу использовать форму для рисования границы пользовательских кнопок, которые мне нужны для моего проекта. вот код для класса, чтобы нарисовать форму изображения:Java - Создайте форму из рамки вокруг изображения

public class CreateShapeClass { 
    public static Area createArea(BufferedImage image, int maxTransparency) { 
     Area area = new Area(); 
     Rectangle rectangle = new Rectangle(); 
     for (int x = 0; x < image.getWidth(); x++) { 
      for (int y = 0; y < image.getHeight(); y++) { 
       int rgb = image.getRGB(x, y); 
       rgb = rgb >>> 24; 
       if (rgb >= maxTransparency) { 
        rectangle.setBounds(x, y, 1, 1); 
        area.add(new Area(rectangle)); 
       } 
      } 
     } 
     return area; 
    } 
} 

однако, это занимает очень много времени, чтобы обработать, и я подумал, что предварительно рисованием фигур в моем главном приложении, а затем хранить их в массив и переход к другим классам, это уменьшит время рендеринга. однако время, затрачиваемое на метод paintBorder() для вычеркивания границы кнопки, занимает довольно много времени (хотя и короче времени, необходимого для рисования фигуры), потому что форма, сгенерированная классом выше, заполняется, а не пустой. Я пытался рисовать фигуры с помощью java2d, например, Ellipse2D, а рендеринг кнопки занимает очень короткое время. любой, кто в этой области может научить меня, как мне создать форму, которая является границей BufferedImage? Я использую класс выше, чтобы создать форму из изображения PNG с прозрачным фоном.

+0

извините, вы можете помочь мне увидеть, какие части используются для получения контура? я не очень хорошо знаком с такими формами и/или:/назовите меня. – csharpnewbie

+0

ах, хорошо, я получил это спасибо! во всяком случае, этот метод действительно очень быстрый по сравнению с классом i, который использовался выше. результат получается менее чем за секунду! в отличие от вышеуказанного метода, который занимает около -13 секунд для обработки. еще раз спасибо! – csharpnewbie

+0

Рад, что вы его отсортировали. :) Я ввел комментарии в качестве ответа, пожалуйста [примите] (http://meta.stackexchange.com/a/65088/155831), когда вы получаете шанс. –

ответ

5

Для получения дополнительной информации см. Smoothing a jagged Путь. Алгоритм получения (грубой) схемы был относительно быстрым в окончательных версиях. Создание GeneralPath удивительно быстрее, чем добавление Area объектов.

Важной частью является этот метод:

public Area getOutline(Color target, BufferedImage bi) { 
    // construct the GeneralPath 
    GeneralPath gp = new GeneralPath(); 

    boolean cont = false; 
    int targetRGB = target.getRGB(); 
    for (int xx=0; xx<bi.getWidth(); xx++) { 
     for (int yy=0; yy<bi.getHeight(); yy++) { 
      if (bi.getRGB(xx,yy)==targetRGB) { 
       if (cont) { 
        gp.lineTo(xx,yy); 
        gp.lineTo(xx,yy+1); 
        gp.lineTo(xx+1,yy+1); 
        gp.lineTo(xx+1,yy); 
        gp.lineTo(xx,yy); 
       } else { 
        gp.moveTo(xx,yy); 
       } 
       cont = true; 
      } else { 
       cont = false; 
      } 
     } 
     cont = false; 
    } 
    gp.closePath(); 

    // construct the Area from the GP & return it 
    return new Area(gp); 
} 
+0

Большое вам спасибо за указание правильного кода! – csharpnewbie

+1

Добро пожаловать. Рад, что моя игра с этим кодом помогла кому-то. :) –

+0

@AndrewThompson Я знаю, что это своего рода некро, но когда я запускаю свой код, я получаю ошибку, из-за которой отсутствует начальный 'moveTo' ... Я попытался реализовать что-то вроде этого' if (first) { gp.moveTo (хх, уу); \t \t first = false; \t} else { \t \t gp.lineTo (xx, yy); \t} 'к коду, но это не помогло ... Спасибо заранее. – nyxaria

Смежные вопросы