图片缩小不失帧

Posted 子阙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图片缩小不失帧相关的知识,希望对你有一定的参考价值。

package com.jeecms.common.image;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.apache.commons.io.FileUtils;

import com.jeecms.common.image.ImageUtils.Position;

/**
 * 图片缩小类。使用方型区域颜色平均算法
 */
public class AverageImageScale {
    /**
     * 缩小图片
     * 
     * @param srcFile
     *            原图片
     * @param destFile
     *            目标图片
     * @param boxWidth
     *            缩略图最大宽度
     * @param boxHeight
     *            缩略图最大高度
     * @throws IOException
     */
    public static void resizeFix(File srcFile, File destFile, int boxWidth,
            int boxHeight) throws IOException {
        BufferedImage srcImgBuff = ImageIO.read(srcFile);
        int width = srcImgBuff.getWidth();
        int height = srcImgBuff.getHeight();
        if (width <= boxWidth && height <= boxHeight) {
            FileUtils.copyFile(srcFile, destFile);
            return;
        }
        int zoomWidth;
        int zoomHeight;
        if ((float) width / height > (float) boxWidth / boxHeight) {
            zoomWidth = boxWidth;
            zoomHeight = Math.round((float) boxWidth * height / width);
        } else {
            zoomWidth = Math.round((float) boxHeight * width / height);
            zoomHeight = boxHeight;
        }
        BufferedImage imgBuff = scaleImage(srcImgBuff, width, height,
                zoomWidth, zoomHeight);
        writeFile(imgBuff, destFile);
    }

    /**
     * 裁剪并压缩
     * 
     * @param srcFile
     *            原文件
     * @param destFile
     *            目标文件
     * @param boxWidth
     *            缩略图最大宽度
     * @param boxHeight
     *            缩略图最大高度
     * @param cutTop
     *            裁剪TOP
     * @param cutLeft
     *            裁剪LEFT
     * @param cutWidth
     *            裁剪宽度
     * @param catHeight
     *            裁剪高度
     * @throws IOException
     */
    public static void resizeFix(File srcFile, File destFile, int boxWidth,
            int boxHeight, int cutTop, int cutLeft, int cutWidth, int catHeight)
            throws IOException {
        BufferedImage srcImgBuff = ImageIO.read(srcFile);
        srcImgBuff = srcImgBuff.getSubimage(cutTop, cutLeft, cutWidth,
                catHeight);
        int width = srcImgBuff.getWidth();
        int height = srcImgBuff.getHeight();
        if (width <= boxWidth && height <= boxHeight) {
            writeFile(srcImgBuff, destFile);
            return;
        }
        int zoomWidth;
        int zoomHeight;
        if ((float) width / height > (float) boxWidth / boxHeight) {
            zoomWidth = boxWidth;
            zoomHeight = Math.round((float) boxWidth * height / width);
        } else {
            zoomWidth = Math.round((float) boxHeight * width / height);
            zoomHeight = boxHeight;
        }
        BufferedImage imgBuff = scaleImage(srcImgBuff, width, height,
                zoomWidth, zoomHeight);
        writeFile(imgBuff, destFile);
    }

    public static void writeFile(BufferedImage imgBuf, File destFile)
            throws IOException {
        File parent = destFile.getParentFile();
        if (!parent.exists()) {
            parent.mkdirs();
        }
        ImageIO.write(imgBuf, "jpeg", destFile);
    }

    /**
     * 添加文字水印
     * 
     * @param srcFile
     *            源图片文件。需要加水印的图片文件。
     * @param destFile
     *            目标图片。加水印后保存的文件。如果和源图片文件一致,则覆盖源图片文件。
     * @param minWidth
     *            需要加水印的最小宽度,如果源图片宽度小于该宽度,则不加水印。
     * @param minHeight
     *            需要加水印的最小高度,如果源图片高度小于该高度,则不加水印。
     * @param pos
     *            加水印的位置。
     * @param offsetX
     *            加水印的位置的偏移量x。
     * @param offsetY
     *            加水印的位置的偏移量y。
     * @param text
     *            水印文字
     * @param color
     *            水印颜色
     * @param size
     *            水印字体大小
     * @param alpha
     *            透明度
     * @throws IOException
     */
    public static void imageMark(File srcFile, File destFile, int minWidth,
            int minHeight, int pos, int offsetX, int offsetY, String text,
            Color color, int size, int alpha) throws IOException {
        BufferedImage imgBuff = ImageIO.read(srcFile);
        int width = imgBuff.getWidth();
        int height = imgBuff.getHeight();
        if (width <= minWidth || height <= minHeight) {
            imgBuff = null;
            if (!srcFile.equals(destFile)) {
                FileUtils.copyFile(srcFile, destFile);
            }
        } else {
            imageMark(imgBuff, width, height, pos, offsetX, offsetY, text,
                    color, size, alpha);
            writeFile(imgBuff, destFile);
            imgBuff = null;
        }
    }

    /**
     * 添加图片水印
     * 
     * @param srcFile
     *            源图片文件。需要加水印的图片文件。
     * @param destFile
     *            目标图片。加水印后保存的文件。如果和源图片文件一致,则覆盖源图片文件。
     * @param minWidth
     *            需要加水印的最小宽度,如果源图片宽度小于该宽度,则不加水印。
     * @param minHeight
     *            需要加水印的最小高度,如果源图片高度小于该高度,则不加水印。
     * @param pos
     *            加水印的位置。
     * @param offsetX
     *            加水印的位置的偏移量x。
     * @param offsetY
     *            加水印的位置的偏移量y。
     * @param markFile
     *            水印图片
     * @throws IOException
     */
    public static void imageMark(File srcFile, File destFile, int minWidth,
            int minHeight, int pos, int offsetX, int offsetY, File markFile)
            throws IOException {
        BufferedImage imgBuff = ImageIO.read(srcFile);
        int width = imgBuff.getWidth();
        int height = imgBuff.getHeight();
        if (width <= minWidth || height <= minHeight) {
            imgBuff = null;
            if (!srcFile.equals(destFile)) {
                FileUtils.copyFile(srcFile, destFile);
            }
        } else {
            imageMark(imgBuff, width, height, pos, offsetX, offsetY, markFile);
            writeFile(imgBuff, destFile);
            imgBuff = null;
        }

    }

    /**
     * 添加文字水印
     * 
     * @param imgBuff
     *            原图片
     * @param width
     *            原图宽度
     * @param height
     *            原图高度
     * @param pos
     *            位置。1:左上;2:右上;3左下;4右下;5:中央;0或其他:随机。
     * @param offsetX
     *            水平偏移量。
     * @param offsetY
     *            垂直偏移量。
     * @param text
     *            水印内容
     * @param color
     *            水印颜色
     * @param size
     *            文字大小
     * @param alpha
     *            透明度。0-100。越小越透明。
     * @throws IOException
     */
    private static void imageMark(BufferedImage imgBuff, int width, int height,
            int pos, int offsetX, int offsetY, String text, Color color,
            int size, int alpha) throws IOException {
        Position p = ImageUtils.markPosition(width, height, pos, offsetX,
                offsetY);
        Graphics2D g = imgBuff.createGraphics();
        g.setColor(color);
        g.setFont(new Font(null, Font.PLAIN, size));
        AlphaComposite a = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                (float) alpha / 100);
        g.setComposite(a);
        g.drawString(text, p.getX(), p.getY());
        g.dispose();
    }

    private static void imageMark(BufferedImage imgBuff, int width, int height,
            int pos, int offsetX, int offsetY, File markFile)
            throws IOException {
        Position p = ImageUtils.markPosition(width, height, pos, offsetX,
                offsetY);
        Graphics2D g = imgBuff.createGraphics();
        AlphaComposite a = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP);
        g.setComposite(a);
        g.drawImage(ImageIO.read(markFile), p.getX(), p.getY(), null);
        g.dispose();
    }

    private static BufferedImage scaleImage(BufferedImage srcImgBuff,
            int width, int height, int zoomWidth, int zoomHeight) {
        int[] colorArray = srcImgBuff.getRGB(0, 0, width, height, null, 0,
                width);
        BufferedImage outBuff = new BufferedImage(zoomWidth, zoomHeight,
                BufferedImage.TYPE_INT_RGB);
        // 宽缩小的倍数
        float wScale = (float) width / zoomWidth;
        int wScaleInt = (int) (wScale + 0.5);
        // 高缩小的倍数
        float hScale = (float) height / zoomHeight;
        int hScaleInt = (int) (hScale + 0.5);
        int area = wScaleInt * hScaleInt;
        int x0, x1, y0, y1;
        int color;
        long red, green, blue;
        int x, y, i, j;
        for (y = 0; y < zoomHeight; y++) {
            // 得到原图高的Y坐标
            y0 = (int) (y * hScale);
            y1 = y0 + hScaleInt;
            for (x = 0; x < zoomWidth; x++) {
                x0 = (int) (x * wScale);
                x1 = x0 + wScaleInt;
                red = green = blue = 0;
                for (i = x0; i < x1; i++) {
                    for (j = y0; j < y1; j++) {
                        color = colorArray[width * j + i];
                        red += getRedValue(color);
                        green += getGreenValue(color);
                        blue += getBlueValue(color);
                    }
                }
                outBuff.setRGB(x, y, comRGB((int) (red / area),
                        (int) (green / area), (int) (blue / area)));
            }
        }
        return outBuff;
    }

    private static int getRedValue(int rgbValue) {
        return (rgbValue & 0x00ff0000) >> 16;
    }

    private static int getGreenValue(int rgbValue) {
        return (rgbValue & 0x0000ff00) >> 8;
    }

    private static int getBlueValue(int rgbValue) {
        return rgbValue & 0x000000ff;
    }

    private static int comRGB(int redValue, int greenValue, int blueValue) {
        return (redValue << 16) + (greenValue << 8) + blueValue;
    }

    public static void main(String[] args) throws Exception {
        long time = System.currentTimeMillis();
        AverageImageScale.resizeFix(new File("D:\\file\\ssh.png"),new File("D:\\file\\ssh.png"), 500, 500);
        /*AverageImageScale.resizeFix(new File(
                "D:\\file\\ssh.png"), new File(
                "D:\\file\\ss.png"), 500, 310, 50, 50,
                320, 320);*/
                 
        /*AverageImageScale.imageMark(new File(
                "D:\\file\\ssh.png"), new File(
                "D:\\file\\ss.png"), 12, 12, 1, 20, 20, "jeecms", Color.red, 40, 100);
        time = System.currentTimeMillis() - time;*/
        System.out.println("resize2 img in " + time + "ms");
    }
}
package com.jeecms.common.image;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 图片辅助类
 */
public abstract class ImageUtils {
    /**
     * 图片的后缀
     */
    public static final String[] IMAGE_EXT = new String[] { "jpg", "jpeg",
            "gif", "png", "bmp" };

    /**
     * 是否是图片
     * 
     * @param ext
     * @return "jpg", "jpeg", "gif", "png", "bmp" 为文件后缀名者为图片
     */
    public static boolean isValidImageExt(String ext) {
        ext = ext.toLowerCase(Locale.ENGLISH);
        for (String s : IMAGE_EXT) {
            if (s.equalsIgnoreCase(ext)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Checks if the underlying input stream contains an image.
     * 
     * @param in
     *            input stream of an image
     * @return <code>true</code> if the underlying input stream contains an
     *         image, else <code>false</code>
     */
    public static boolean isImage(final InputStream in) {
        ImageInfo ii = new ImageInfo();
        ii.setInput(in);
        return ii.check();
    }

    /**
     * 获得水印位置
     * 
     * @param width
     *            原图宽度
     * @param height
     *            原图高度
     * @param p
     *            水印位置 1-5,其他值为随机。1:左上;2:右上;3:左下;4:右下;5:中央。
     * @param offsetx
     *            水平偏移。
     * @param offsety
     *            垂直偏移。
     * @return 水印位置
     */
    public static Position markPosition(int width, int height, int p,
            int offsetx, int offsety) {
        if (p < 1 || p > 5) {
            p = (int) (Math.random() * 5) + 1;
        }
        int x, y;
        switch (p) {
        // 左上
        case 1:
            x = offsetx;
            y = offsety;
            break;
        // 右上
        case 2:
            x = width + offsetx;
            y = offsety;
            break;
        // 左下
        case 3:
            x = offsetx;
            y = height + offsety;
            break;
        // 右下
        case 4:
            x = width + offsetx;
            y = height + offsety;
            break;
        // 中央
        case 5:
            x = (width / 2) + offsetx;
            y = (height / 2) + offsety;
            break;
        default:
            throw new RuntimeException("never reach ...");
        }
        return new Position(x, y);
    }

    /**
     * 水印位置
     * 
     * 包含左边偏移量,右边偏移量。
     */
    public static class Position {
        private int x;
        private int y;

        public Position(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int getX() {
            return x;
        }

        public void setX(int x) {
            this.x = x;
        }

        public int getY() {
            return y;
        }

        public void setY(int y) {
            this.y = y;
        }
    }
    

    public static  List<String> getImageSrc(String htmlCode) {  
        List<String> imageSrcList = new ArrayList<String>();  
        String regular="<img(.*?)src=\"(.*?)\"";  
        String img_pre="(?i)<img(.*?)src=\"";
        String img_sub="\"";
        Pattern p=Pattern.compile(regular,Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(htmlCode);  
        String src = null;  
        while (m.find()) {  
            src=m.group();
            src=src.replaceAll(img_pre, "").replaceAll(img_sub, "").trim();
            imageSrcList.add(src);  
        }  
        return imageSrcList;  
    }

}

 

图片的处理,欢迎留言...

 

以上是关于图片缩小不失帧的主要内容,如果未能解决你的问题,请参考以下文章

堪称神器的图片无损放大缩小工具

堪称神器的图片无损放大缩小工具

Image图片自适应 Image resizeMode属性

如何利用ffmpeg将一小段视频截取成图片

求一个简单的点击图片放大缩小的JS代码

求一个简单的点击图片放大缩小的JS代码