The biggest headache is still about how to display the verification code, achieve the effect of distortion and random font color, and compress the specified image into the specified location.
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; public class CaptchaLoginFrame extends JFrame { private JTextField usernameField; private JPasswordField passwordField; private JTextField captchaInputField; private JLabel captchaLabel; private String captchaText; private BufferedImage captchaImage; private static final int CAPTCHA_WIDTH = 120; private static final int CAPTCHA_HEIGHT = 40; public CaptchaLoginFrame() { initializeUI(); } private void initializeUI() { setTitle("Login form with picture verification code"); setDefaultCloseOperation(EXIT_ON_CLOSE); setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(4, 4, 4, 4); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 0; gbc.gridy = 0; add(new JLabel("Username:"), gbc); usernameField = new JTextField(20); gbc.gridx = 1; gbc.gridy = 0; gbc.gridwidth = 3; add(usernameField, gbc); gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 1; add(new JLabel("password:"), gbc); passwordField = new JPasswordField(20); gbc.gridx = 1; gbc.gridy = 1; gbc.gridwidth = 3; add(passwordField, gbc); gbc.gridx = 0; gbc.gridy = 2; gbc.gridwidth = 1; add(new JLabel("Verification code:"), gbc); captchaInputField = new JTextField(4); gbc.gridx = 1; gbc.gridy = 2; gbc.gridwidth = 1; add(captchaInputField, gbc); regenerateCaptcha(); gbc.gridx = 2; gbc.gridy = 2; gbc.gridwidth = 1; add(captchaLabel, gbc); JButton changeCaptchaButton = new JButton("Change one"); changeCaptchaButton.addActionListener(e -> regenerateCaptcha()); gbc.gridx = 3; gbc.gridy = 2; add(changeCaptchaButton, gbc); JButton loginButton = new JButton("Login"); loginButton.addActionListener(e -> performLogin()); JButton resetButton = new JButton("Reset"); resetButton.addActionListener(e -> resetFields()); JPanel buttonPanel = new JPanel(new FlowLayout()); buttonPanel.add(loginButton); buttonPanel.add(resetButton); gbc.gridx = 0; gbc.gridy = 3; gbc.gridwidth = 4; add(buttonPanel, gbc); pack(); setLocationRelativeTo(null); } private void resetFields() { usernameField.setText(""); passwordField.setText(""); captchaInputField.setText(""); regenerateCaptcha(); } private void regenerateCaptcha() { captchaText = generateCaptchaText(4); captchaImage = generateCaptchaImage(captchaText); if (captchaLabel == null) { captchaLabel = new JLabel(new ImageIcon(captchaImage)); } else { captchaLabel.setIcon(new ImageIcon(captchaImage)); } captchaLabel.repaint(); } private BufferedImage generateCaptchaImage(String text) { try { BufferedImage originalImage = ImageIO.read(new File("F:\Wallpaper\wallhaven-gpmjxe_1920x1080.png")); Image scaledImage = originalImage.getScaledInstance(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, Image.SCALE_SMOOTH); BufferedImage image = new BufferedImage(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = image.createGraphics(); g2d.drawImage(scaledImage, 0, 0, null); Font font = new Font("Arial", Font.BOLD, 24); g2d.setFont(font); g2d.setColor(Color.black); Random random = new Random(); int x = 10; for (char c : text.toCharArray()) { double theta = (random.nextDouble() - 0.5) * Math.PI / 4; AffineTransform affineTransform = AffineTransform.getRotateInstance(theta, 0, 0); Font rotatedFont = font.deriveFont(affineTransform); g2d.setFont(rotatedFont); g2d.drawString(String.valueOf(c), x, CAPTCHA_HEIGHT / 2 + 10); x + = g2d.getFontMetrics().charWidth(c) + 5; } g2d.dispose(); return image; } catch (IOException e) { e.printStackTrace(); return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); } } private void performLogin() { String username = usernameField.getText(); String password = new String(passwordField.getPassword()); String inputCaptcha = captchaInputField.getText(); if (username.isEmpty()) { JOptionPane.showMessageDialog(this, "Account is empty", "Login error", JOptionPane.ERROR_MESSAGE); return; } if (password.isEmpty()) { JOptionPane.showMessageDialog(this, "Password is empty", "Login error", JOptionPane.ERROR_MESSAGE); return; } if (!inputCaptcha.equalsIgnoreCase(captchaText)) { JOptionPane.showMessageDialog(this, "Verification code error", "Login error", JOptionPane.ERROR_MESSAGE); regenerateCaptcha(); return; } JOptionPane.showMessageDialog(this, "Login successful", "Login", JOptionPane.INFORMATION_MESSAGE); } private String generateCaptchaText(int length) { String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; StringBuilder sb = new StringBuilder(); Random random = new Random(); for (int i = 0; i < length; i + + ) { sb.append(chars.charAt(random.nextInt(chars.length()))); } return sb.toString(); } public static void main(String[] args) { SwingUtilities.invokeLater(() -> new CaptchaLoginFrame().setVisible(true)); } } /*private BufferedImage generateCaptchaImage(String text) { try { // Load the background image from a file BufferedImage originalImage = ImageIO.read(new File("F:\Wallpaper\wallhaven-gpmjxe_1920x1080.png")); // Resize image to fit the captcha dimensions Image scaledImage = originalImage.getScaledInstance(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, Image.SCALE_SMOOTH); BufferedImage image = new BufferedImage(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = image.createGraphics(); // Draw the resized image g2d.drawImage(scaledImage, 0, 0, null); // Set font Font font = new Font("Arial", Font.BOLD, 24); g2d.setFont(font); // Randomize the positioning and rotation of each character Random random = new Random(); int x = 10; // Start at 10 pixels from left for (char c : text.toCharArray()) { // Random angle from -45 to + 45 degrees double theta = (random.nextDouble() - 0.5) * Math.PI / 4; AffineTransform affineTransform = AffineTransform.getRotateInstance(theta, 0, 0); Font rotatedFont = font.deriveFont(affineTransform); g2d.setFont(rotatedFont); // Set a random color for each character g2d.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256))); // Draw the character g2d.drawString(String.valueOf(c), x, CAPTCHA_HEIGHT / 2 + 10); // Move to the right for the next character x + = g2d.getFontMetrics().charWidth(c) + 5; } g2d.dispose(); return image; } catch (IOException e) { e.printStackTrace(); return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); } } */
1. The following is an iterative version, which is more perfect.
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; public class CaptchaLoginFrame extends JFrame { private JTextField usernameField; private JPasswordField passwordField; private JTextField captchaInputField; private JLabel captchaLabel; private String captchaText; private BufferedImage captchaImage; private static final int CAPTCHA_WIDTH = 120; private static final int CAPTCHA_HEIGHT = 40; public CaptchaLoginFrame() { initializeUI(); } private void initializeUI() { setTitle("Login form with picture verification code"); setDefaultCloseOperation(EXIT_ON_CLOSE); setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(4, 4, 4, 4); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 0; gbc.gridy = 0; add(new JLabel("Username:"), gbc); usernameField = new JTextField(20); gbc.gridx = 1; gbc.gridy = 0; gbc.gridwidth = 3; add(usernameField, gbc); gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 1; add(new JLabel("password:"), gbc); passwordField = new JPasswordField(20); gbc.gridx = 1; gbc.gridy = 1; gbc.gridwidth = 3; add(passwordField, gbc); gbc.gridx = 0; gbc.gridy = 2; gbc.gridwidth = 1; add(new JLabel("Verification code:"), gbc); captchaInputField = new JTextField(4); gbc.gridx = 1; gbc.gridy = 2; gbc.gridwidth = 1; add(captchaInputField, gbc); regenerateCaptcha(); gbc.gridx = 2; gbc.gridy = 2; gbc.gridwidth = 1; add(captchaLabel, gbc); JButton changeCaptchaButton = new JButton("Change one"); changeCaptchaButton.addActionListener(e -> regenerateCaptcha()); gbc.gridx = 3; gbc.gridy = 2; add(changeCaptchaButton, gbc); JButton loginButton = new JButton("Login"); loginButton.addActionListener(e -> performLogin()); JButton resetButton = new JButton("Reset"); resetButton.addActionListener(e -> resetFields()); JPanel buttonPanel = new JPanel(new FlowLayout()); buttonPanel.add(loginButton); buttonPanel.add(resetButton); gbc.gridx = 0; gbc.gridy = 3; gbc.gridwidth = 4; add(buttonPanel, gbc); pack(); setLocationRelativeTo(null); } private void resetFields() { usernameField.setText(""); passwordField.setText(""); captchaInputField.setText(""); regenerateCaptcha(); } private void regenerateCaptcha() { captchaText = generateCaptchaText(4); captchaImage = generateCaptchaImage(captchaText); if (captchaLabel == null) { captchaLabel = new JLabel(new ImageIcon(captchaImage)); } else { captchaLabel.setIcon(new ImageIcon(captchaImage)); } captchaLabel.repaint(); } private BufferedImage generateCaptchaImage(String text) { try { BufferedImage originalImage = ImageIO.read(new File("F:\Wallpaper\wallhaven-gpmjxe_1920x1080.png")); Image scaledImage = originalImage.getScaledInstance(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, Image.SCALE_SMOOTH); BufferedImage image = new BufferedImage(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = image.createGraphics(); g2d.drawImage(scaledImage, 0, 0, null); Font font = new Font("Arial", Font.BOLD, 24); g2d.setFont(font); Random random = new Random(); int x = 10; for (char c : text.toCharArray()) { // Random angle from -45 to + 45 degrees double theta = (random.nextDouble() - 0.5) * Math.PI / 4; AffineTransform affineTransform = AffineTransform.getRotateInstance(theta, 0, 0); Font rotatedFont = font.deriveFont(affineTransform); g2d.setFont(rotatedFont); // Set a random color for each character g2d.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256))); // Draw the character g2d.drawString(String.valueOf(c), x, CAPTCHA_HEIGHT / 2 + 10); // Move to the right for the next character x + = g2d.getFontMetrics().charWidth(c) + 5; } g2d.dispose(); return image; } catch (IOException e) { e.printStackTrace(); return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); } } private void performLogin() { String username = usernameField.getText(); String password = new String(passwordField.getPassword()); String inputCaptcha = captchaInputField.getText(); //Verify username and password boolean isAuthenticated = "admin".equals(username) & amp; & amp; "1234".equals(password); if (!isAuthenticated) { JOptionPane.showMessageDialog(this, "Account or password error", "Login error", JOptionPane.ERROR_MESSAGE); return; } if (!inputCaptcha.equalsIgnoreCase(captchaText)) { JOptionPane.showMessageDialog(this, "Verification code error", "Login error", JOptionPane.ERROR_MESSAGE); regenerateCaptcha(); return; } //The account number, password and verification code are correct JOptionPane.showMessageDialog(this, "Login successful", "Login", JOptionPane.INFORMATION_MESSAGE); } private String generateCaptchaText(int length) { String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; StringBuilder sb = new StringBuilder(); Random random = new Random(); for (int i = 0; i < length; i + + ) { sb.append(chars.charAt(random.nextInt(chars.length()))); } return sb.toString(); } public static void main(String[] args) { SwingUtilities.invokeLater(() -> new CaptchaLoginFrame().setVisible(true)); } }
Keep warm when it’s cold!
The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 139365 people are learning the system