• 大型网站对图片的下载,存放,及压缩管理


    构建保存图片的路径:

    View Code
    1 String pathdir = "/images/product/"+ productTypeId+ "/"+ productId+ "/prototype";//构建文件保存的目录  

    为什么要有那么多个目录,因为java本身不会去获取图片,而是调用了操作系统的一些接口来获取图片,如果一个目录下图片太多的话,操作系统获取图片的速度会变慢 ,所以巴巴运动网在构建图片路径的时候搞了多个目录,分散保存图片。

     

    有了这个pathdir就可以得到图片保存目录的真实路径:

    View Code
    1 String realpathdir = request.getSession().getServletContext().getRealPath(pathdir);

    获取了图片的真实路径后,就可以开始保存图片了: 

    View Code
    1 File savedir = new File(realpathdir);
    2 File file = saveFile(savedir, filename, imagefile.getFileData());

    imagefile为struts的FormFile类的对象,filename为文件名,这两个属性都可以从前台获取过来。以下是saveFile方法的代码: 

    View Code
     1 /**
    2 * 保存文件
    3 * @param savedir 存放目录
    4 * @param fileName 文件名称
    5 * @param data 保存的内容
    6 * @return 保存的文件
    7 * @throws Exception
    8 */
    9 public static File saveFile(File savedir, String fileName, byte[] data) throws Exception{
    10 if(!savedir.exists()) savedir.mkdirs();//如果目录不存在就创建
    11 File file = new File(savedir, fileName);
    12 FileOutputStream fileoutstream = new FileOutputStream(file);
    13 fileoutstream.write(data);
    14 fileoutstream.close();
    15 return file;
    16 }

    保存完图片后还要保存一张图片的缩略图,宽度为140px 

     

    View Code
    1 String pathdir140 = "/images/product/"+ productTypeId+ "/"+ productId+ "/140x";//140宽度的图片保存目录
    2 String realpathdir140 = request.getSession().getServletContext().getRealPath(pathdir140);
    3 File savedir140 = new File(realpathdir140);
    4 if(!savedir140.exists()) savedir140.mkdirs();//如果目录不存在就创建
    5 File file140 = new File(realpathdir140, filename);
    6 ImageSizer.resize(file, file140, 140, ext);

    这里我们用到了一个从网上下的用于压缩图片的ImageSizer工具类的静态方法,resize方法传进去的四个参数分别代表原始图片对象,需要被压缩的图片对象,压缩宽度的大小,图片后缀名。这个工具类只能压缩jpg, png, gif(非动画)三种格式,如果想压缩更多的格式需要付费。以下是该工具类: 

     

    View Code
      1 /**
    2 * 图像压缩工具
    3 * @author lihuoming@sohu.com
    4 *
    5 */
    6 public class ImageSizer {
    7 public static final MediaTracker tracker = new MediaTracker(new Component() {
    8 private static final long serialVersionUID = 1234162663955668507L;}
    9 );
    10 /**
    11 * @param originalFile 原图像
    12 * @param resizedFile 压缩后的图像
    13 * @param width 图像宽
    14 * @param format 图片格式 jpg, png, gif(非动画)
    15 * @throws IOException
    16 */
    17 public static void resize(File originalFile, File resizedFile, int width, String format) throws IOException {
    18 if(format!=null && "gif".equals(format.toLowerCase())){
    19 resize(originalFile, resizedFile, width, 1);
    20 return;
    21 }
    22 FileInputStream fis = new FileInputStream(originalFile);
    23 ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    24 int readLength = -1;
    25 int bufferSize = 1024;
    26 byte bytes[] = new byte[bufferSize];
    27 while ((readLength = fis.read(bytes, 0, bufferSize)) != -1) {
    28 byteStream.write(bytes, 0, readLength);
    29 }
    30 byte[] in = byteStream.toByteArray();
    31 fis.close();
    32 byteStream.close();
    33
    34 Image inputImage = Toolkit.getDefaultToolkit().createImage( in );
    35 waitForImage( inputImage );
    36 int imageWidth = inputImage.getWidth( null );
    37 if ( imageWidth < 1 )
    38 throw new IllegalArgumentException( "image width " + imageWidth + " is out of range" );
    39 int imageHeight = inputImage.getHeight( null );
    40 if ( imageHeight < 1 )
    41 throw new IllegalArgumentException( "image height " + imageHeight + " is out of range" );
    42
    43 // Create output image.
    44 int height = -1;
    45 double scaleW = (double) imageWidth / (double) width;
    46 double scaleY = (double) imageHeight / (double) height;
    47 if (scaleW >= 0 && scaleY >=0) {
    48 if (scaleW > scaleY) {
    49 height = -1;
    50 } else {
    51 width = -1;
    52 }
    53 }
    54 Image outputImage = inputImage.getScaledInstance( width, height, java.awt.Image.SCALE_DEFAULT);
    55 checkImage( outputImage );
    56 encode(new FileOutputStream(resizedFile), outputImage, format);
    57 }
    58
    59 /** Checks the given image for valid width and height. */
    60 private static void checkImage( Image image ) {
    61 waitForImage( image );
    62 int imageWidth = image.getWidth( null );
    63 if ( imageWidth < 1 )
    64 throw new IllegalArgumentException( "image width " + imageWidth + " is out of range" );
    65 int imageHeight = image.getHeight( null );
    66 if ( imageHeight < 1 )
    67 throw new IllegalArgumentException( "image height " + imageHeight + " is out of range" );
    68 }
    69
    70 /** Waits for given image to load. Use before querying image height/width/colors. */
    71 private static void waitForImage( Image image ) {
    72 try {
    73 tracker.addImage( image, 0 );
    74 tracker.waitForID( 0 );
    75 tracker.removeImage(image, 0);
    76 } catch( InterruptedException e ) { e.printStackTrace(); }
    77 }
    78
    79 /** Encodes the given image at the given quality to the output stream. */
    80 private static void encode( OutputStream outputStream, Image outputImage, String format )
    81 throws java.io.IOException {
    82 int outputWidth = outputImage.getWidth( null );
    83 if ( outputWidth < 1 )
    84 throw new IllegalArgumentException( "output image width " + outputWidth + " is out of range" );
    85 int outputHeight = outputImage.getHeight( null );
    86 if ( outputHeight < 1 )
    87 throw new IllegalArgumentException( "output image height " + outputHeight + " is out of range" );
    88
    89 // Get a buffered image from the image.
    90 BufferedImage bi = new BufferedImage( outputWidth, outputHeight,
    91 BufferedImage.TYPE_INT_RGB );
    92 Graphics2D biContext = bi.createGraphics();
    93 biContext.drawImage( outputImage, 0, 0, null );
    94 ImageIO.write(bi, format, outputStream);
    95 outputStream.flush();
    96 }
    97
    98 /**
    99 * 缩放gif图片
    100 * @param originalFile 原图片
    101 * @param resizedFile 缩放后的图片
    102 * @param newWidth 宽度
    103 * @param quality 缩放比例 (等比例)
    104 * @throws IOException
    105 */
    106 private static void resize(File originalFile, File resizedFile, int newWidth, float quality) throws IOException {
    107 if (quality < 0 || quality > 1) {
    108 throw new IllegalArgumentException("Quality has to be between 0 and 1");
    109 }
    110 ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
    111 Image i = ii.getImage();
    112 Image resizedImage = null;
    113 int iWidth = i.getWidth(null);
    114 int iHeight = i.getHeight(null);
    115 if (iWidth > iHeight) {
    116 resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight) / iWidth, Image.SCALE_SMOOTH);
    117 } else {
    118 resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight, newWidth, Image.SCALE_SMOOTH);
    119 }
    120 // This code ensures that all the pixels in the image are loaded.
    121 Image temp = new ImageIcon(resizedImage).getImage();
    122 // Create the buffered image.
    123 BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null),
    124 BufferedImage.TYPE_INT_RGB);
    125 // Copy image to buffered image.
    126 Graphics g = bufferedImage.createGraphics();
    127 // Clear background and paint the image.
    128 g.setColor(Color.white);
    129 g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
    130 g.drawImage(temp, 0, 0, null);
    131 g.dispose();
    132 // Soften.
    133 float softenFactor = 0.05f;
    134 float[] softenArray = {0, softenFactor, 0, softenFactor, 1-(softenFactor*4), softenFactor, 0, softenFactor, 0};
    135 Kernel kernel = new Kernel(3, 3, softenArray);
    136 ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
    137 bufferedImage = cOp.filter(bufferedImage, null);
    138 // Write the jpeg to a file.
    139 FileOutputStream out = new FileOutputStream(resizedFile);
    140 // Encodes image as a JPEG data stream
    141 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
    142 JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);
    143 param.setQuality(quality, true);
    144 encoder.setJPEGEncodeParam(param);
    145 encoder.encode(bufferedImage);
    146 }
    147 }

    允许用户上传文件,那么我们一定要注意安全,如果用户上传了一个jsp文件,而这个文件的上传路径恰好能被用户访问到,那么用户可能会在这个jsp文件里面做一个对网站其他文件的文件操作,可以将文件保存到web-inf下面,如果用户需要下载,我们就写一个servlet读取这个文件,以流的方式返回给用户。 

  • 相关阅读:
    golang json处理
    关于单例模式中懒汉模式和饿汉模式的学习
    关于Lambda表达式的研究
    左值和右值得研究
    关于epoll的详解说明关于epoll的详解说明
    关于c++中条件变量的分析
    关于c++种std::function和bind的用法
    关于iterator_traits的使用
    STL容器之deque数据结构解析
    STL容器之Array的用法
  • 原文地址:https://www.cnblogs.com/jerryxing/p/2436603.html
Copyright © 2020-2023  润新知