sinat_14811783 2015-02-06 14:22 采纳率: 0%
浏览 2216

求教!看不懂的Java代码

package org.sun.web.identicon;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.math.BigInteger;

/**

  • 9-block Identicon renderer.
  • Current implementation uses only the lower 32 bits of identicon code.
  • @author don
  • */
    public class NineBlockIdenticonRenderer2 implements IdenticonRenderer {

    /*

    • Each patch is a polygon created from a list of vertices on a 5 by 5 grid.
    • Vertices are numbered from 0 to 24, starting from top-left corner of the
    • grid, moving left to right and top to bottom. */

    private static final int PATCH_GRIDS = 5;

    private static final float DEFAULT_PATCH_SIZE = 20.0f;

    private static final byte PATCH_SYMMETRIC = 1;

    private static final byte PATCH_INVERTED = 2;

    private static final int PATCH_MOVETO = -1;

    private static final byte[] patch0 = { 0, 4, 24, 20 };

    private static final byte[] patch1 = { 0, 4, 20 };

    private static final byte[] patch2 = { 2, 24, 20 };

    private static final byte[] patch3 = { 0, 2, 20, 22 };

    private static final byte[] patch4 = { 2, 14, 22, 10 };

    private static final byte[] patch5 = { 0, 14, 24, 22 };

    private static final byte[] patch6 = { 2, 24, 22, 13, 11, 22, 20 };

    private static final byte[] patch7 = { 0, 14, 22 };

    private static final byte[] patch8 = { 6, 8, 18, 16 };

    private static final byte[] patch9 = { 4, 20, 10, 12, 2 };

    private static final byte[] patch10 = { 0, 2, 12, 10 };

    private static final byte[] patch11 = { 10, 14, 22 };

    private static final byte[] patch12 = { 20, 12, 24 };

    private static final byte[] patch13 = { 10, 2, 12 };

    private static final byte[] patch14 = { 0, 2, 10 };

    private static final byte[] patchTypes[] = { patch0, patch1, patch2,
    patch3, patch4, patch5, patch6, patch7, patch8, patch9, patch10,
    patch11, patch12, patch13, patch14, patch0 };

    private static final byte patchFlags[] = { PATCH_SYMMETRIC, 0, 0, 0,
    PATCH_SYMMETRIC, 0, 0, 0, PATCH_SYMMETRIC, 0, 0, 0, 0, 0, 0,
    PATCH_SYMMETRIC + PATCH_INVERTED };

    private static int centerPatchTypes[] = { 0, 4, 8, 15 };

    private float patchSize;

    private GeneralPath[] patchShapes;

    // used to center patch shape at origin because shape rotation works
    // correctly.
    private float patchOffset;

    private Color backgroundColor = Color.WHITE;

    /**

    • Constructor.
    • */ public NineBlockIdenticonRenderer2() { setPatchSize(DEFAULT_PATCH_SIZE); }

    /**

    • Returns the size in pixels at which each patch will be rendered before
    • they are scaled down to requested identicon size.
    • @return */ public float getPatchSize() { return patchSize; }

    /**

    • Set the size in pixels at which each patch will be rendered before they
    • are scaled down to requested identicon size. Default size is 20 pixels
    • which means, for 9-block identicon, a 60x60 image will be rendered and
    • scaled down.
    • @param size
    • patch size in pixels */ public void setPatchSize(float size) { this.patchSize = size; this.patchOffset = patchSize / 2.0f; // used to center patch shape at float patchScale = patchSize / 4.0f; // origin. this.patchShapes = new GeneralPath[patchTypes.length]; for (int i = 0; i < patchTypes.length; i++) { GeneralPath patch = new GeneralPath(GeneralPath.WIND_NON_ZERO); boolean moveTo = true; byte[] patchVertices = patchTypes[i]; for (int j = 0; j < patchVertices.length; j++) { int v = (int) patchVertices[j]; if (v == PATCH_MOVETO) moveTo = true; float vx = ((v % PATCH_GRIDS) * patchScale) - patchOffset; float vy = ((float) Math.floor(((float) v) / PATCH_GRIDS)) * patchScale - patchOffset; if (!moveTo) { patch.lineTo(vx, vy); } else { moveTo = false; patch.moveTo(vx, vy); } } patch.closePath(); this.patchShapes[i] = patch; } }

    public Color getBackgroundColor() {
    return backgroundColor;
    }

    public void setBackgroundColor(Color backgroundColor) {
    this.backgroundColor = backgroundColor;
    }

    public BufferedImage render(BigInteger code, int size) {
    return renderQuilt(code.intValue(), size);
    }

    /**

    • Returns rendered identicon image for given identicon code.
    • Size of the returned identicon image is determined by patchSize set using
    • {@link setPatchSize}. Since a 9-block identicon consists of 3x3 patches,
    • width and height will be 3 times the patch size.
    • @param code
    • identicon code
    • @param size
    • image size
    • @return identicon image */ public BufferedImage render(int code, int size) { return renderQuilt(code, size); }

    protected BufferedImage renderQuilt(int code, int size) {
    // -------------------------------------------------
    // PREPARE
    //

    // decode the code into parts
    // bit 0-1: middle patch type
    // bit 2: middle invert
    // bit 3-6: corner patch type
    // bit 7: corner invert
    // bit 8-9: corner turns
    // bit 10-13: side patch type
    // bit 14: side invert
    // bit 15: corner turns
    // bit 16-20: blue color component
    // bit 21-26: green color component
    // bit 27-31: red color component
    // 与运算符 计算出一个下标
    int middleType = centerPatchTypes[code & 0x3];
    boolean middleInvert = ((code >> 2) & 0x1) != 0;
    int cornerType = (code >> 3) & 0x0f;
    boolean cornerInvert = ((code >> 7) & 0x1) != 0;
    int cornerTurn = (code >> 8) & 0x3;
    int sideType = (code >> 10) & 0x0f;
    boolean sideInvert = ((code >> 14) & 0x1) != 0;
    int sideTurn = (code >> 15) & 0x3;
    int blue = (code >> 16) & 0x01f;
    int green = (code >> 21) & 0x01f;
    int red = (code >> 27) & 0x01f;
    
    // color components are used at top of the range for color difference
    // use white background for now.
    // TODO: support transparency.
    Color fillColor = new Color(red << 3, green << 3, blue << 3);
    
    // outline shapes with a noticeable color (complementary will do) if
    // shape color and background color are too similar (measured by color
    // distance).
    Color strokeColor = null;
    if (getColorDistance(fillColor, backgroundColor) < 32.0f)
        strokeColor = getComplementaryColor(fillColor);
    
    // -------------------------------------------------
    // RENDER
    //
    
    BufferedImage targetImage = new BufferedImage(size, size,
            BufferedImage.TYPE_INT_RGB);
    Graphics2D g = targetImage.createGraphics();
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    
    g.setBackground(backgroundColor);
    g.clearRect(0, 0, size, size);
    
    float blockSize = size / 3.0f;
    float blockSize2 = blockSize * 2.0f;
    
    // middle patch
    drawPatch(g, blockSize, blockSize, blockSize, middleType, 0,
            middleInvert, fillColor, strokeColor);
    
    // side patchs, starting from top and moving clock-wise
    drawPatch(g, blockSize, 0, blockSize, sideType, sideTurn++, sideInvert,
            fillColor, strokeColor);
    drawPatch(g, blockSize2, blockSize, blockSize, sideType, sideTurn++,
            sideInvert, fillColor, strokeColor);
    drawPatch(g, blockSize, blockSize2, blockSize, sideType, sideTurn++,
            sideInvert, fillColor, strokeColor);
    drawPatch(g, 0, blockSize, blockSize, sideType, sideTurn++, sideInvert,
            fillColor, strokeColor);
    
    // corner patchs, starting from top left and moving clock-wise
    drawPatch(g, 0, 0, blockSize, cornerType, cornerTurn++, cornerInvert,
            fillColor, strokeColor);
    drawPatch(g, blockSize2, 0, blockSize, cornerType, cornerTurn++,
            cornerInvert, fillColor, strokeColor);
    drawPatch(g, blockSize2, blockSize2, blockSize, cornerType,
            cornerTurn++, cornerInvert, fillColor, strokeColor);
    drawPatch(g, 0, blockSize2, blockSize, cornerType, cornerTurn++,
            cornerInvert, fillColor, strokeColor);
    
    g.dispose();
    
    return targetImage;
    

    }

    private void drawPatch(Graphics2D g, float x, float y, float size,
    int patch, int turn, boolean invert, Color fillColor,
    Color strokeColor) {
    assert patch >= 0;
    assert turn >= 0;
    patch %= patchTypes.length;
    turn %= 4;
    if ((patchFlags[patch] & PATCH_INVERTED) != 0)
    invert = !invert;

    Shape shape = patchShapes[patch];
    double scale = ((double) size) / ((double) patchSize);
    float offset = size / 2.0f;
    
    // paint background
    g.setColor(invert ? fillColor : backgroundColor);
    g.fill(new Rectangle2D.Float(x, y, size, size));
    
    AffineTransform savet = g.getTransform();
    g.translate(x + offset, y + offset);
    g.scale(scale, scale);
    g.rotate(Math.toRadians(turn * 90));
    
    // if stroke color was specified, apply stroke
    // stroke color should be specified if fore color is too close to the
    // back color.
    if (strokeColor != null) {
        g.setColor(strokeColor);
        g.draw(shape);
    }
    
    // render rotated patch using fore color (back color if inverted)
    g.setColor(invert ? backgroundColor : fillColor);
    g.fill(shape);
    
    g.setTransform(savet);
    

    }

    /**

    • Returns distance between two colors.
    • @param c1
    • @param c2
    • @return */ private float getColorDistance(Color c1, Color c2) { float dx = c1.getRed() - c2.getRed(); float dy = c1.getGreen() - c2.getGreen(); float dz = c1.getBlue() - c2.getBlue(); return (float) Math.sqrt(dx * dx + dy * dy + dz * dz); }

    /**

    • Returns complementary color.
    • @param color
    • @return */ private Color getComplementaryColor(Color color) { return new Color(color.getRGB() ^ 0x00FFFFFF); } }
  • 写回答

4条回答 默认 最新

  • xiaofeiren2 2015-02-06 14:26
    关注

    先让代码跑起来,应该就可以知道是什么了

    评论

报告相同问题?

悬赏问题

  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置