/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package tools; import constants.ServerConstants; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.font.TextAttribute; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.text.AttributedString; import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import provider.MapleData; import provider.MapleDataProvider; import provider.MapleDataProviderFactory; import provider.MapleDataTool; /** * * @author Pungin */ public class CheckCodeImageCreator { public static Color getRandColor(int start, int end) { Random random = new Random(); if (start > 255) { start = 255; } if (end > 255) { end = 255; } int randNum; if (start > end) { randNum = start - end; } else { randNum = end - start; } int r = start + random.nextInt(randNum); int g = start + random.nextInt(randNum); int b = start + random.nextInt(randNum); return new Color(r, g, b); } public static String getRandWord(int length, int width, int height, Graphics2D g) { Random random = new Random(); String finalWord = "", firstWord = ""; MapleData data; MapleDataProvider dataProvider = MapleDataProviderFactory.getDataProvider("String.wz"); data = dataProvider.getData("Mob.img"); List<String> mobNameList = new LinkedList<>(); for (MapleData mobIdData : data.getChildren()) { mobNameList.add(MapleDataTool.getString(mobIdData.getChildByPath("name"), "")); } for (int i = 0; i < length; i++) { firstWord = ""; switch (ServerConstants.MAPLE_TYPE) { case 한국: case 日本: case 中国: case 台港澳: while (firstWord.isEmpty()) { String name = mobNameList.get(random.nextInt(mobNameList.size())); name = name.replaceAll("[a-zA-Z]", ""); name = name.replaceAll("[^\\pL]", ""); if (!name.isEmpty()) { int nameX = random.nextInt(name.length()); firstWord = name.substring(nameX, nameX + 1); break; } } break; default: if (random.nextInt(2) == 1) { // 大寫字母還是小寫字母 int temp = random.nextInt(2) == 0 ? 0x41 : 0x61; firstWord = String.valueOf((char) (random.nextInt(0x1A) + temp)); } else { firstWord = String.valueOf(random.nextInt(10)); } } finalWord += firstWord; coloredAndRotation(firstWord, i, g, length, width, height); } return finalWord; } public static void coloredAndRotation(String word, int i, Graphics2D g2d, int length, int width, int height) { Random random = new Random(); g2d.setColor(getRandColor(5, 100)); FontMetrics fm = g2d.getFontMetrics(); Rectangle2D rc = fm.getStringBounds(word, g2d); int x = width / length / 2 + width * i / length; int y = height / 2 + 10 - random.nextInt(11); int rRand = random.nextInt(30); AffineTransform trans = new AffineTransform(); trans.rotate((-15.0 + rRand) * Math.PI / 180.0, x, y); float scaleSize = random.nextFloat() + 0.8F; if (scaleSize > 1F) { scaleSize = 1F; } trans.scale(scaleSize, scaleSize); g2d.setTransform(trans); for (int j = 1; j >= 0; j--) { if (j == 1) { g2d.setComposite(AlphaComposite.SrcOver.derive(0.5F)); } else { g2d.setComposite(AlphaComposite.SrcOver.derive(1.0F)); } if (random.nextInt(2) == 0) { AttributedString as = new AttributedString(word); as.addAttribute(TextAttribute.FONT, g2d.getFont()); as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, 0, 1); g2d.drawString(as.getIterator(), x - (int) (rc.getCenterX()), y + (fm.getHeight() - fm.getDescent()) / 2 * j + random.nextInt(fm.getDescent() / 2)); } else { g2d.drawString(word, x - (int) (rc.getCenterX()), y + (fm.getHeight() - fm.getDescent()) / 2 * j + random.nextInt(fm.getDescent() / 2)); } } } public static Pair<String, File> createCheckCode() { int width = 196, height = 44; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D) image.getGraphics(); Random random = new Random(); g.setColor(getRandColor(254, 255)); g.fillRect(0, 0, width, height); int point = 2000 + random.nextInt(500); for (int i = 0; i < point; i++) { g.setColor(getRandColor(80, 150)); int x = random.nextInt(width); int y = random.nextInt(height); int z = random.nextInt(2); g.fillRect(x, y, z, z); } int line = 2 + random.nextInt(3); for (int i = 0; i < line; i++) { g.setColor(getRandColor(80, 150)); int x = random.nextInt(width - 50); int y = random.nextInt(height + 20); int xl = 50 + random.nextInt(50); int yl = -20 + random.nextInt(50); g.drawLine(x, y, x + xl, y + yl); } String fontStr = ""; switch (ServerConstants.MAPLE_TYPE) { case 한국: fontStr = "Batang"; break; case 日本: fontStr = "MS Gothic"; break; case 中国: fontStr = "KaiTi"; break; case 台港澳: fontStr = "DFKai-SB"; break; default: fontStr = "Arial"; } Font font = new Font(fontStr, Font.BOLD + Font.ITALIC, 25); g.setFont(font); String sRand = getRandWord(4, width, height, g); if (sRand.isEmpty()) { return null; } g.dispose(); File file = null; try { file = File.createTempFile("MapleStoryCheckCode", ""); ImageIO.write(image, "JPEG", file); } catch (IOException ex) { Logger.getLogger(CheckCodeImageCreator.class.getName()).log(Level.SEVERE, null, ex); } if (file == null) { return null; } return new Pair(sRand, file); } public static void main(String[] args) throws FileNotFoundException, IOException { Pair<String, File> checkCode = createCheckCode(); FileInputStream fis = new FileInputStream(checkCode.getRight()); File toFile = new File(checkCode.getLeft() + ".jpg"); if (toFile.exists()) { toFile.delete(); } toFile.createNewFile(); FileOutputStream fout = new FileOutputStream(toFile); byte[] date = new byte[512]; int rs = -1; while ((rs = fis.read(date)) > 0) { fout.write(date, 0, rs); } fout.close(); fis.close(); } }