|
| 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