Я пытаюсь написать программу для рисования полигонов и заполнения их желаемым цветом. Это простое приложение для рисования, но проблема, с которой я столкнулась, - это когда я рисую многоугольники и рисую их то между полигонами появляется тонкая белая линия. Но когда я не сглаживаю полигоны, тогда белая линия исчезает, но полигоны не являются гладкими. И реальная проблема в том, что мне нужно иметь гладкие полигоны, а также белую тонкую линию также нужно удалить.Призрачная белая линия появляется при сглаживании многоугольников в JAVA
Класс рисовать многоугольник является:
public class GrayScaleManager{
private final VisualizerController controller;
private final BufferedImage grayScaledImage;
private final HashMap<ToolsModel, BufferedImage> grayScaleportionList;
public GrayScaleManager(VisualizerController drawingCanvas) {
this.controller = drawingCanvas;
grayScaleportionList = new HashMap<>();
grayScaledImage = toGray(Utility.bufferedImageDeepCopy(Util.getImg()));
}
public void grayScaleSelectedPortion(Graphics2D g, ToolsModel selectedArea) {
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setClip((Shape) selectedArea);
g.drawImage(grayScaledImage, 0, 0, null);
g.setClip(null);
}
private BufferedImage toGray(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
Color c = new Color(image.getRGB(j, i));
int red = (int) (c.getRed() * 0.3);
int green = (int) (c.getGreen() * 0.59);
int blue = (int) (c.getBlue() * 0.11);
int sum = red + green + blue;
Color newColor = new Color(sum, sum, sum);
image.setRGB(j, i, newColor.getRGB());
}
}
return image;
}
public VisualizerController getController() {
return controller;
}
public HashMap<ToolsModel, BufferedImage> getGrayScaleportionList() {
return grayScaleportionList;
}
}
И образ, что я получаю, когда я бегу код являются
Собственно код вращается в traingle (3 сценариев) :
Сценарий 1: Если код выполняется как этот
public void grayScaleSelectedPotion(Graphics2D g, ToolsModel selectedArea){
g.setClip((Shape) selectedArea);
g.drawImage(grayScaledImage, 0, 0, null);
g.setClip(null);
}
Плюсы: 1. Если несколько слоев нарисованы путем совпадения друг с другом одного цвета, слои кажутся одиночными (один слой). 2. Не призраков белых линий. Против: 1. Кромки линий не являются гладкими.
Сценарий 2: Если применяется визуализация, просто применяя ниже код внутри выше метода.
public void grayScaleSelectedPotion(Graphics2D g, ToolsModel selectedArea){
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setClip((Shape) selectedArea);
g.drawImage(grayScaledImage, 0, 0, null);
g.setClip(null);
}
За: 1. Один слой. 2. Ребра гладкие. Против: 1. Появляются белые пояса призраков.
Сценарий 3: Если вынесено, но DrawImage() удален
public void grayScaleSelectedPotion(Graphics2D g, ToolsModel selectedArea){
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setClip((Shape) selectedArea);
// g.drawImage(grayScaledImage, 0, 0, null);
g.setClip(null);
}
Pros: 1. Края являются гладкими. 2. Не призраков белых линий.
Против: 1. Несколько слоев отчетливо видны, даже слои имеют одинаковые цвета (что неприемлемо).
В заключение, все три недостатка в трех сценариях должны быть очищены.
После внедрения решения от @MadProgrammer код выглядит как:
super.paintComponent(g);
grayImage = grayScaleManager.getGrayImage();
BufferedImage mask = new BufferedImage(img.getWidth(),img.getHeight(),BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = mask.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
shadeList.forEach((shape)->{
g2d.setColor(shape.getColor());
if (shape.getColor().getAlpha() != NULL_ALPHA) {
//g2d.fill((Shape)shape);
}
g2d.fill((Shape)shape);
if (shape.getColor().getAlpha() == SELECTION_ALPHA) {
g2d.setStroke(new BasicStroke(1));
g2d.setColor(Color.red.brighter().brighter().brighter());
g2d.draw((Shape) shape);
}
});
// g2d.dispose();
masked = applyMask(mask,grayImage,AlphaComposite.SRC_IN);
g.drawImage(img,0,0,null);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 0.0f));
g.drawImage(masked, 0, 0, this);
g2d.dispose();
g.dispose();
}
/*Added methods for the changes applymask method*/
public static BufferedImage applyMask(BufferedImage sourceImage, BufferedImage maskImage, int method) {
System.out.println("I am in applymask");
BufferedImage maskedImage = null;
if (sourceImage != null) {
System.out.println("I am in applymask in if case");
int width = maskImage.getWidth(null);
int height = maskImage.getHeight(null);
maskedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D mg = maskedImage.createGraphics();
int x = (width - sourceImage.getWidth(null))/2;
int y = (height - sourceImage.getHeight(null))/2;
//mg.setColor(Color.RED);
//mg.drawImage(sourceImage, x, y, null);
mg.drawImage(sourceImage, 0, 0, null);
mg.setComposite(AlphaComposite.getInstance(method,0.0f));
mg.dispose();
}
return maskedImage;
}
Но теперь grayScaledImage не красится и многоугольники накладываются друг на друга, и когда grayScaledImage добавляется то мы не можем добавить другие цвета к многоугольнику.
Из памяти 'setClip' не генерирует« мягкие »ребра – MadProgrammer
@MadProgrammer, пожалуйста, вы можете быть более выразительными. –
Если вы используете 'setClip', вы не получите преимущества сглаживания (из памяти), посмотрите на [Soft Clipping] (https://community.oracle.com/blogs/campbell/2006/07/ 19/java-2d-trickery-soft-clipping) для некоторых идей. Вы также должны использовать 'Graphics # create' и' Graphics # dispose', которые позволят вам вносить изменения в контекст (например, с помощью 'setClip'), который не будет переноситься на – MadProgrammer