Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 40 additions & 15 deletions HMCL/src/main/java/org/jackhuang/hmcl/theme/Themes.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.SetChangeListener;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.image.Image;
import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.PixelFormat;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
Expand Down Expand Up @@ -78,6 +78,9 @@
import org.jetbrains.annotations.NotNullByDefault;
import org.jetbrains.annotations.Nullable;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -941,10 +944,11 @@ private static Background createThemeColorBackground(double opacity) {

/// Creates a JavaFX image background with the requested opacity.
private static Background createBackgroundWithOpacity(Image image, double opacity) {
PixelReader pixelReader = image.getPixelReader();
if (image == null) return null;

if (opacity <= 0) {
return new Background(new BackgroundFill(new Color(1, 1, 1, 0), CornerRadii.EMPTY, Insets.EMPTY));
} else if (opacity >= 1. || pixelReader == null) {
} else if (opacity >= 1.0 || image.getPixelReader() == null) {
return new Background(new BackgroundImage(
image,
BackgroundRepeat.NO_REPEAT,
Expand All @@ -953,22 +957,43 @@ private static Background createBackgroundWithOpacity(Image image, double opacit
new BackgroundSize(800, 480, false, false, true, true)
));
} else {
WritableImage tempImage = new WritableImage((int) image.getWidth(), (int) image.getHeight());
PixelWriter pixelWriter = tempImage.getPixelWriter();
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
Color color = pixelReader.getColor(x, y);
Color newColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), color.getOpacity() * opacity);
pixelWriter.setColor(x, y, newColor);
}
int targetWidth = 800;
int targetHeight = 480;

double imageWidth = image.getWidth();
double imageHeight = image.getHeight();

double scale = Math.max(targetWidth / imageWidth, targetHeight / imageHeight);

BufferedImage srcBuffered = SwingFXUtils.fromFXImage(image, null);

BufferedImage destBuffered = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = destBuffered.createGraphics();

AffineTransform at = new AffineTransform();
at.scale(scale, scale);
g2d.drawImage(srcBuffered, at, null);
g2d.dispose();

WritableImage tempImage = SwingFXUtils.toFXImage(destBuffered, null);

int[] buffer = new int[targetWidth * targetHeight];
tempImage.getPixelReader().getPixels(0, 0, targetWidth, targetHeight, PixelFormat.getIntArgbInstance(), buffer, 0, targetWidth);

int alphaMultiplier = (int) (opacity * 255);
for (int i = 0; i < buffer.length; i++) {
int argb = buffer[i];
int a = ((argb >>> 24) * alphaMultiplier) / 255;
buffer[i] = (a << 24) | (argb & 0x00FFFFFF);
}

tempImage.getPixelWriter().setPixels(0, 0, targetWidth, targetHeight, PixelFormat.getIntArgbInstance(), buffer, 0, targetWidth);

return new Background(new BackgroundImage(
tempImage,
BackgroundRepeat.NO_REPEAT,
BackgroundRepeat.NO_REPEAT,
BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT,
BackgroundPosition.DEFAULT,
new BackgroundSize(800, 480, false, false, true, true)
new BackgroundSize(targetWidth, targetHeight, false, false, true, true)
));
Comment thread
KSSJW marked this conversation as resolved.
}
}
Expand Down