Skip to content

Commit bfd774a

Browse files
committed
Add 04-visual-editor: Interactive split-screen demo with resize, blur, grayscale controls
1 parent a0903fe commit bfd774a

3 files changed

Lines changed: 262 additions & 93 deletions

File tree

RELEASE_DESCRIPTION.txt

Lines changed: 0 additions & 93 deletions
This file was deleted.

examples/04-visual-editor/pom.xml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
6+
<modelVersion>4.0.0</modelVersion>
7+
8+
<groupId>fastimage.examples</groupId>
9+
<artifactId>visual-editor</artifactId>
10+
<version>1.0.0</version>
11+
<packaging>jar</packaging>
12+
13+
<name>FastImage - Visual Editor</name>
14+
<description>Interactive split-screen editor with resize, blur, grayscale, brightness controls</description>
15+
16+
<properties>
17+
<maven.compiler.source>17</maven.compiler.source>
18+
<maven.compiler.target>17</maven.compiler.target>
19+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
20+
</properties>
21+
22+
<repositories>
23+
<repository>
24+
<id>jitpack.io</id>
25+
<url>https://jitpack.io</url>
26+
</repository>
27+
</repositories>
28+
29+
<dependencies>
30+
<dependency>
31+
<groupId>com.github.andrestubbe</groupId>
32+
<artifactId>fastimage</artifactId>
33+
<version>v1.0.0</version>
34+
</dependency>
35+
</dependencies>
36+
37+
<build>
38+
<plugins>
39+
<plugin>
40+
<groupId>org.codehaus.mojo</groupId>
41+
<artifactId>exec-maven-plugin</artifactId>
42+
<version>3.1.0</version>
43+
<configuration>
44+
<mainClass>fastimage.VisualEditor</mainClass>
45+
</configuration>
46+
</plugin>
47+
</plugins>
48+
</build>
49+
</project>
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
package fastimage;
2+
3+
import javax.swing.*;
4+
import javax.swing.event.ChangeEvent;
5+
import java.awt.*;
6+
import java.awt.image.BufferedImage;
7+
8+
/**
9+
* VisualEditor - Interaktiver Split-Screen Editor
10+
*
11+
* Links: Original Bild
12+
* Rechts: Bearbeitetes Bild (FastImage)
13+
*
14+
* Controls:
15+
* - Resize Slider
16+
* - Blur Radius
17+
* - Grayscale Toggle
18+
* - Brightness/Contrast
19+
*/
20+
public class VisualEditor extends JFrame {
21+
22+
private BufferedImage original;
23+
private JLabel originalLabel, resultLabel, statusLabel;
24+
25+
// Controls
26+
private JCheckBox cbResize, cbBlur, cbGrayscale;
27+
private JSlider sliderResize, sliderBlur, sliderBrightness, sliderContrast;
28+
private JButton btnReset, btnApply;
29+
30+
public VisualEditor() {
31+
setTitle("FastImage Visual Editor - Live Preview");
32+
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
33+
setLayout(new BorderLayout(10, 10));
34+
35+
// Generate colorful test image
36+
original = generateTestImage(800, 600);
37+
38+
// Left panel - image comparison
39+
JPanel imagePanel = new JPanel(new GridLayout(1, 2, 10, 0));
40+
imagePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
41+
42+
originalLabel = new JLabel("Original", SwingConstants.CENTER);
43+
originalLabel.setBorder(BorderFactory.createTitledBorder("Original (BufferedImage)"));
44+
originalLabel.setIcon(new ImageIcon(original));
45+
46+
resultLabel = new JLabel("Result", SwingConstants.CENTER);
47+
resultLabel.setBorder(BorderFactory.createTitledBorder("FastImage Result (SIMD Accelerated)"));
48+
resultLabel.setIcon(new ImageIcon(original));
49+
50+
imagePanel.add(originalLabel);
51+
imagePanel.add(resultLabel);
52+
53+
add(imagePanel, BorderLayout.CENTER);
54+
55+
// Right controls panel
56+
JPanel controls = new JPanel(new GridLayout(8, 1, 5, 5));
57+
controls.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
58+
controls.setPreferredSize(new Dimension(300, 0));
59+
60+
// Resize
61+
JPanel resizePanel = new JPanel(new BorderLayout());
62+
cbResize = new JCheckBox("Resize (50-100%)");
63+
sliderResize = new JSlider(50, 100, 100);
64+
resizePanel.add(cbResize, BorderLayout.WEST);
65+
resizePanel.add(sliderResize, BorderLayout.CENTER);
66+
controls.add(resizePanel);
67+
68+
// Blur
69+
JPanel blurPanel = new JPanel(new BorderLayout());
70+
cbBlur = new JCheckBox("Blur (0-10px)");
71+
sliderBlur = new JSlider(0, 10, 0);
72+
blurPanel.add(cbBlur, BorderLayout.WEST);
73+
blurPanel.add(sliderBlur, BorderLayout.CENTER);
74+
controls.add(blurPanel);
75+
76+
// Grayscale
77+
cbGrayscale = new JCheckBox("Grayscale");
78+
controls.add(cbGrayscale);
79+
80+
// Brightness
81+
JPanel brightPanel = new JPanel(new BorderLayout());
82+
brightPanel.add(new JLabel("Brightness: "), BorderLayout.WEST);
83+
sliderBrightness = new JSlider(50, 150, 100);
84+
brightPanel.add(sliderBrightness, BorderLayout.CENTER);
85+
controls.add(brightPanel);
86+
87+
// Contrast
88+
JPanel contrastPanel = new JPanel(new BorderLayout());
89+
contrastPanel.add(new JLabel("Contrast: "), BorderLayout.WEST);
90+
sliderContrast = new JSlider(50, 150, 100);
91+
contrastPanel.add(sliderContrast, BorderLayout.CENTER);
92+
controls.add(contrastPanel);
93+
94+
// Buttons
95+
JPanel buttonPanel = new JPanel(new FlowLayout());
96+
btnReset = new JButton("🔄 Reset");
97+
btnApply = new JButton("⚡ Apply FastImage");
98+
btnReset.addActionListener(e -> resetControls());
99+
btnApply.addActionListener(e -> applyEffects());
100+
buttonPanel.add(btnReset);
101+
buttonPanel.add(btnApply);
102+
controls.add(buttonPanel);
103+
104+
// Status
105+
statusLabel = new JLabel("Click 'Apply' to process with FastImage SIMD");
106+
statusLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
107+
controls.add(statusLabel);
108+
109+
add(controls, BorderLayout.EAST);
110+
111+
pack();
112+
setLocationRelativeTo(null);
113+
}
114+
115+
private void applyEffects() {
116+
long start = System.nanoTime();
117+
118+
FastImage img = FastImage.fromBufferedImage(original);
119+
120+
// Apply enabled effects
121+
if (cbResize.isSelected()) {
122+
int percent = sliderResize.getValue();
123+
int w = original.getWidth() * percent / 100;
124+
int h = original.getHeight() * percent / 100;
125+
img.resize(w, h);
126+
}
127+
128+
if (cbBlur.isSelected() && sliderBlur.getValue() > 0) {
129+
img.blur(sliderBlur.getValue());
130+
}
131+
132+
if (cbGrayscale.isSelected()) {
133+
img.grayscale();
134+
}
135+
136+
float brightness = sliderBrightness.getValue() / 100f;
137+
float contrast = sliderContrast.getValue() / 100f;
138+
139+
if (brightness != 1.0f) {
140+
img.adjustBrightness(brightness);
141+
}
142+
143+
if (contrast != 1.0f) {
144+
img.adjustContrast(contrast);
145+
}
146+
147+
BufferedImage result = img.toBufferedImage();
148+
img.dispose();
149+
150+
long time = (System.nanoTime() - start) / 1_000_000;
151+
152+
resultLabel.setIcon(new ImageIcon(result));
153+
statusLabel.setText(String.format("✅ Processed in %d ms (SIMD accelerated)", time));
154+
}
155+
156+
private void resetControls() {
157+
cbResize.setSelected(false);
158+
cbBlur.setSelected(false);
159+
cbGrayscale.setSelected(false);
160+
sliderResize.setValue(100);
161+
sliderBlur.setValue(0);
162+
sliderBrightness.setValue(100);
163+
sliderContrast.setValue(100);
164+
resultLabel.setIcon(new ImageIcon(original));
165+
statusLabel.setText("Reset - click 'Apply' to process");
166+
}
167+
168+
private BufferedImage generateTestImage(int w, int h) {
169+
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
170+
Graphics2D g = img.createGraphics();
171+
172+
// Rainbow gradient background
173+
for (int x = 0; x < w; x++) {
174+
float hue = (float) x / w;
175+
g.setColor(Color.getHSBColor(hue, 0.8f, 1.0f));
176+
g.fillRect(x, 0, 1, h);
177+
}
178+
179+
// Sharp geometric shapes (test for blur/resize quality)
180+
g.setColor(Color.WHITE);
181+
for (int i = 0; i < 5; i++) {
182+
int x = (i * w / 5) + 40;
183+
int y = h / 4;
184+
int size = 80;
185+
g.fillRect(x, y, size, size);
186+
g.setColor(Color.BLACK);
187+
g.drawRect(x, y, size, size);
188+
g.setColor(Color.WHITE);
189+
}
190+
191+
// Text (sharpness test)
192+
g.setFont(new Font("Arial", Font.BOLD, 72));
193+
g.setColor(Color.YELLOW);
194+
g.drawString("FASTIMAGE", w/4, h/2);
195+
196+
// Fine detail (noise pattern)
197+
g.setColor(new Color(255, 255, 255, 100));
198+
for (int i = 0; i < 200; i++) {
199+
int x = (int)(Math.random() * w);
200+
int y = (int)(Math.random() * h);
201+
g.fillRect(x, y, 2, 2);
202+
}
203+
204+
g.dispose();
205+
return img;
206+
}
207+
208+
public static void main(String[] args) {
209+
SwingUtilities.invokeLater(() -> {
210+
new VisualEditor().setVisible(true);
211+
});
212+
}
213+
}

0 commit comments

Comments
 (0)