2014年4月10日

Java2D旋转图片边缘锯齿问题

在使用Java2D旋转图片时,如果旋转的角度不是45度的倍数,图片边缘会产生非常明显的锯齿。

旋转的代码如下:

public static BufferedImage rotate(BufferedImage image, double angle) {
    double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
    int w = image.getWidth(), h = image.getHeight();
    int neww = (int) Math.floor(w * cos + h * sin), newh = (int) Math.floor(h * cos + w * sin);
    BufferedImage result = new BufferedImage(neww, newh, BufferedImage.TYPE_INT_ARGB_PRE); 
    Graphics2D g = result.createGraphics();
    g.addRenderingHints(RENDER_HINT);
    g.translate((neww - w) / 2, (newh - h) / 2);
    g.rotate(angle, w / 2, h / 2);
    g.drawRenderedImage(image, null);
    g.dispose();
    return result;
}

其中已经加上了相应的RenderingHints:

private static HashMap<Object, Object> RENDER_HINT = new HashMap<Object, Object>();
static{
    RENDER_HINT.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
    RENDER_HINT.put(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    RENDER_HINT.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
    RENDER_HINT.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    RENDER_HINT.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
}

现在对下面这张图片旋转-10度

BufferedImage logo = ImageIO.read(new File("logo.png"));
BufferedImage rotated = rotate(logo, Math.toRadians(-10));

旋转后的图片如下,图片边缘的锯齿惨不忍睹

这里有个取巧的方法可以产生出效果比较好的图片,那就是在旋转前先处理一下图片,给图片加上1-3个像素的透明边框:

public static BufferedImage prerotate(BufferedImage image) {
    BufferedImage temp =
            new BufferedImage(image.getWidth() + 2, image.getHeight() + 2,
                    BufferedImage.TYPE_INT_ARGB_PRE);
    Graphics2D g = temp.createGraphics();
    g.addRenderingHints(RENDER_HINT);
    g.drawImage(image, 1, 1, null);
    g.dispose();
    return temp;
}

先调用一下prerotaterotate,产生的图片效果就好很多了:

2014年2月18日

给cab加数字签名

如果拿到的证书是pfx格式,首先需要生成pvk和spc文件
pfx生成pvk和spc的步骤如下:

  1. openssl pkcs12 -in xxx.pfx -nocerts -nodes -out xxx.key
  2. pvk -in xxx.key -topvk -out xxx.pvk
  3. openssl pkcs12 -in xxx.pfx -nokeys -out xxx.pem
  4. openssl crl2pkcs7 -nocrl -certfile xxx.pem -outform DER -out xxx.spc

然后运行signtool signwizard打开图形界面对cab签名,大致步骤如下:

  1. 选择要签名的cab文件
  2. 选择自定义
  3. 从文件选择 xxx.spc
  4. 磁盘上的私钥文件 xxx.pvk
  5. 选择sha1
  6. 之后一直下一步到完成即可

用到的pvk和signtool:https://dl.dropboxusercontent.com/u/1970520/share/signtool.7z