Issue
I'm trying to draw scaled image on canvas in javafx. Using this code:
Image image = ...;
canvas.setWidth(scale * width);
canvas.setHeight(scale * height);
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.drawImage(image, 0, 0, scale * width, scale * height);
// this gives same result
// gc.scale(scale, scale);
// gc.drawImage(editableImage, 0, 0, width, height);
It works really fast but makes blurred images like this:
This is not what I'd like to see. Instead I want to get this picture:
Which can be drawn by manually setting each pixel color with such code:
PixelReader reader = image.getPixelReader();
PixelWriter writer = gc.getPixelWriter();
for (int y = 0; y < scale * height; ++y) {
for (int x = 0; x < scale * width; ++x) {
writer.setArgb(x, y, reader.getArgb(x / scale, y / scale));
}
}
But I cannot use this approach as it's too slow. It took couple of seconds to draw 1Kb image scaled 8 times. So I ask if there's any way to disable this blurry effect for drawing on canvas?
Solution
UPD 10/07/2019:
Looks like the issue is fixed! Now GraphicsContext should have property "image smoothing" controlling this behavior.
INITIAL ANSWER
I guess I've found answer to my question. As this issue says that there's no way to specify filtering options in graphics context.
Description:
When drawing an image in a GraphicsContext using the drawImage() method to enlarge a small image to a larger canvas, the image is being interpolated (possibly using a bilinear or bicubic algorithm). But there are times like when rendering color maps (temperature, zooplancton, salinity, etc.) or some geographical data (population concentration, etc.) where we want to have no interpolation at all (ie: use the nearest neighbor algorithm instead) in order to represent accurate data and shapes.
In Java2D, this is possible by setting the appropriate RenderingHints.KEY_RENDERING on the Graphics2D at hand. Currently on JavaFX's GraphicsContext there is no such way to specify how the image is to be interpolated.
The same applies when shrinking images too.
This could be expanded to support a better form of smoothing for the "smooth" value that is available in both Image and ImageView and that does not seem to work very well currently (at least on Windows).
The issue was created in 2013 but it's still untouched so unlikely it will be resolved soon.
Answered By - Nolan
Answer Checked By - Clifford M. (JavaFixing Volunteer)