网络传输过程中,为什么要对图像和视频流进行压缩
第一,压缩的必要性:图象和视频通常在计算机中表示后会占用非常大的空间,而出于节省硬盘空间的考虑,往往要进行压缩。同时,传输过程中,为了节省珍贵的带宽资源和节省时间,也迫切要求压缩。压缩之后,传输过程中的误码率也会相应地减少。
第二,压缩的可能性:
人眼对颜色只有一定的感应能力,当某些颜色十分相近时,人是感觉不出差异的(或者很小)。这一点为压缩提供了机会。我们把相近的颜色用一种颜色表示,从而减少了图象的存储空间,实现压缩。同时,通过解压缩,我们可以根据之前采取的压缩方法(有损压缩、无损压缩等)进行相应的解压缩措施,保证图象的真度恢复。
下面是个人封装的工具,具有用户自定义图片压缩水印(图片水印,文字水印)、图片透明处理、灰白处理、格式获取、格式转换、物理存储、处理中介BufferedImage等模块.
代码全贴,含注释, 个人娱乐之作,不喜勿喷! 菜鸟一枚,求指点.
1 package org.dennisit.org.util; 2 import java.awt.AlphaComposite; 3 import java.awt.Color; 4 import java.awt.Font; 5 import java.awt.Graphics2D; 6 import java.awt.Image; 7 import java.awt.color.ColorSpace; 8 import java.awt.image.BufferedImage; 9 import java.awt.image.ColorConvertOp; 10 import java.io.ByteArrayInputStream; 11 import java.io.File; 12 import java.io.FileInputStream; 13 import java.io.IOException; 14 import java.util.Iterator; 15 16 import javax.imageio.ImageIO; 17 import javax.imageio.ImageReader; 18 import javax.imageio.stream.MemoryCacheImageInputStream; 19 20 import com.sun.imageio.plugins.bmp.BMPImageReader; 21 import com.sun.imageio.plugins.gif.GIFImageReader; 22 import com.sun.imageio.plugins.jpeg.JPEGImageReader; 23 import com.sun.imageio.plugins.png.PNGImageReader; 24 25 /** 26 * 27 * @version : 1.1 28 * 29 * @author : 苏若年 发送邮件 30 * 31 * @since : 1.0 创建时间: 2012-12-28 上午11:15:03 32 * 33 * @function: 图片工具类 34 * 35 * 36 * 37 */ 38 39 public class PictureUtil { 40 41 public static final float DEFAULT_QUALITY = 0.2125f ; 42 43 44 /** 45 * 46 * 添加图片水印操作(物理存盘,使用默认格式) 47 * 48 * @param imgPath 49 * 待处理图片 50 * @param markPath 51 * 水印图片 52 * @param x 53 * 水印位于图片左上角的 x 坐标值 54 * @param y 55 * 水印位于图片左上角的 y 坐标值 56 * @param alpha 57 * 水印透明度 0.1f ~ 1.0f 58 * @param destPath 59 * 文件存放路径 60 * @throws Exception 61 * 62 */ 63 public static void addWaterMark(String imgPath, String markPath, int x, int y, float alpha,String destPath) throws Exception{ 64 try { 65 BufferedImage bufferedImage = addWaterMark(imgPath, markPath, x, y, alpha); 66 ImageIO.write(bufferedImage, imageFormat(imgPath), new File(destPath)); 67 } catch (Exception e) { 68 throw new RuntimeException("添加图片水印异常"); 69 } 70 } 71 72 73 /** 74 * 75 * 添加图片水印操作(物理存盘,自定义格式) 76 * 77 * @param imgPath 78 * 待处理图片 79 * @param markPath 80 * 水印图片 81 * @param x 82 * 水印位于图片左上角的 x 坐标值 83 * @param y 84 * 水印位于图片左上角的 y 坐标值 85 * @param alpha 86 * 水印透明度 0.1f ~ 1.0f 87 * @param format 88 * 添加水印后存储的格式 89 * @param destPath 90 * 文件存放路径 91 * @throws Exception 92 * 93 */ 94 public static void addWaterMark(String imgPath, String markPath, int x, int y, float alpha,String format,String destPath) throws Exception{ 95 try { 96 BufferedImage bufferedImage = addWaterMark(imgPath, markPath, x, y, alpha); 97 ImageIO.write(bufferedImage,format , new File(destPath)); 98 } catch (Exception e) { 99 throw new RuntimeException("添加图片水印异常");100 }101 }102 103 104 /**105 * 106 * 添加图片水印操作,返回BufferedImage对象107 * 108 * @param imgPath109 * 待处理图片110 * @param markPath111 * 水印图片112 * @param x113 * 水印位于图片左上角的 x 坐标值114 * @param y115 * 水印位于图片左上角的 y 坐标值116 * @param alpha117 * 水印透明度 0.1f ~ 1.0f118 * @return119 * 处理后的图片对象120 * @throws Exception 121 * 122 */123 public static BufferedImage addWaterMark(String imgPath, String markPath, int x, int y, float alpha) throws Exception{124 BufferedImage targetImage = null;125 try {126 // 加载待处理图片文件127 Image img = ImageIO.read(new File(imgPath));128 129 //创建目标图象文件130 targetImage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);131 Graphics2D g = targetImage.createGraphics();132 g.drawImage(img, 0, 0, null);133 134 // 加载水印图片文件135 Image markImg = ImageIO.read(new File(markPath));136 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));137 g.drawImage(markImg, x, y, null);138 g.dispose();139 } catch (Exception e) {140 throw new RuntimeException("添加图片水印操作异常");141 }142 return targetImage;143 144 }145 146 147 148 /**149 * 150 * 添加文字水印操作(物理存盘,使用默认格式)151 * 152 * @param imgPath153 * 待处理图片154 * @param text155 * 水印文字 156 * @param font157 * 水印字体信息 不写默认值为宋体158 * @param color159 * 水印字体颜色160 * @param x161 * 水印位于图片左上角的 x 坐标值162 * @param y163 * 水印位于图片左上角的 y 坐标值164 * @param alpha165 * 水印透明度 0.1f ~ 1.0f166 * @param format167 * 添加水印后存储的格式168 * @param destPath169 * 文件存放路径 170 * @throws Exception 171 */172 public static void addTextMark(String imgPath, String text, Font font, Color color, float x, float y, float alpha,String destPath) throws Exception{173 try {174 BufferedImage bufferedImage = addTextMark(imgPath, text, font, color, x, y, alpha);175 ImageIO.write(bufferedImage, imageFormat(imgPath), new File(destPath));176 } catch (Exception e) {177 throw new RuntimeException("图片添加文字水印异常");178 }179 }180 181 /**182 * 183 * 添加文字水印操作(物理存盘,自定义格式)184 * 185 * @param imgPath186 * 待处理图片187 * @param text188 * 水印文字 189 * @param font190 * 水印字体信息 不写默认值为宋体191 * @param color192 * 水印字体颜色193 * @param x194 * 水印位于图片左上角的 x 坐标值195 * @param y196 * 水印位于图片左上角的 y 坐标值197 * @param alpha198 * 水印透明度 0.1f ~ 1.0f199 * @param format200 * 添加水印后存储的格式201 * @param destPath202 * 文件存放路径 203 * @throws Exception 204 */205 public static void addTextMark(String imgPath, String text, Font font, Color color, float x, float y, float alpha,String format,String destPath) throws Exception{206 try {207 BufferedImage bufferedImage = addTextMark(imgPath, text, font, color, x, y, alpha);208 ImageIO.write(bufferedImage, format, new File(destPath));209 } catch (Exception e) {210 throw new RuntimeException("图片添加文字水印异常");211 }212 }213 214 /**215 * 216 * 添加文字水印操作,返回BufferedImage对象217 * 218 * @param imgPath219 * 待处理图片220 * @param text221 * 水印文字 222 * @param font223 * 水印字体信息 不写默认值为宋体224 * @param color225 * 水印字体颜色226 * @param x227 * 水印位于图片左上角的 x 坐标值228 * @param y229 * 水印位于图片左上角的 y 坐标值230 * @param alpha231 * 水印透明度 0.1f ~ 1.0f232 * @return233 * 处理后的图片对象234 * @throws Exception 235 */236 237 public static BufferedImage addTextMark(String imgPath, String text, Font font, Color color, float x, float y, float alpha) throws Exception{238 BufferedImage targetImage = null;239 try {240 Font Dfont = (font == null) ? new Font("宋体", 20, 13) : font; 241 Image img = ImageIO.read(new File(imgPath));242 //创建目标图像文件243 targetImage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);244 Graphics2D g = targetImage.createGraphics();245 g.drawImage(img, 0, 0, null);246 g.setColor(color);247 g.setFont(Dfont);248 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));249 g.drawString(text, x, y);250 g.dispose();251 } catch (Exception e) {252 throw new RuntimeException("添加文字水印操作异常");253 }254 return targetImage;255 }256 257 258 259 /**260 * 261 * 262 * 263 * 压缩图片操作(文件物理存盘,使用默认格式)264 * 265 * @param imgPath266 * 待处理图片267 * @param quality268 * 图片质量(0-1之間的float值)269 * @param width270 * 输出图片的宽度 输入负数参数表示用原来图片宽271 * @param height272 * 输出图片的高度 输入负数参数表示用原来图片高273 * @param autoSize274 * 是否等比缩放 true表示进行等比缩放 false表示不进行等比缩放275 * @param format276 * 压缩后存储的格式277 * @param destPath278 * 文件存放路径279 * 280 * @throws Exception281 */282 public static void compressImage(String imgPath,float quality,int width, int height, boolean autoSize,String destPath)throws Exception{283 try {284 BufferedImage bufferedImage = compressImage(imgPath, quality, width, height, autoSize);285 ImageIO.write(bufferedImage, imageFormat(imgPath), new File(destPath));286 } catch (Exception e) {287 throw new RuntimeException("图片压缩异常");288 }289 290 }291 292 293 /**294 * 295 * 压缩图片操作(文件物理存盘,可自定义格式)296 * 297 * @param imgPath298 * 待处理图片299 * @param quality300 * 图片质量(0-1之間的float值)301 * @param width302 * 输出图片的宽度 输入负数参数表示用原来图片宽303 * @param height304 * 输出图片的高度 输入负数参数表示用原来图片高305 * @param autoSize306 * 是否等比缩放 true表示进行等比缩放 false表示不进行等比缩放307 * @param format308 * 压缩后存储的格式309 * @param destPath310 * 文件存放路径311 * 312 * @throws Exception313 */314 public static void compressImage(String imgPath,float quality,int width, int height, boolean autoSize,String format,String destPath)throws Exception{315 try {316 BufferedImage bufferedImage = compressImage(imgPath, quality, width, height, autoSize);317 ImageIO.write(bufferedImage, format, new File(destPath));318 } catch (Exception e) {319 throw new RuntimeException("图片压缩异常");320 }321 }322 323 324 /**325 * 326 * 压缩图片操作,返回BufferedImage对象327 * 328 * @param imgPath329 * 待处理图片330 * @param quality331 * 图片质量(0-1之間的float值)332 * @param width333 * 输出图片的宽度 输入负数参数表示用原来图片宽334 * @param height335 * 输出图片的高度 输入负数参数表示用原来图片高336 * @param autoSize337 * 是否等比缩放 true表示进行等比缩放 false表示不进行等比缩放338 * @return339 * 处理后的图片对象340 * @throws Exception341 */342 public static BufferedImage compressImage(String imgPath,float quality,int width, int height, boolean autoSize)throws Exception{343 BufferedImage targetImage = null;344 if(quality<0F||quality>1F){345 quality = DEFAULT_QUALITY;346 }347 try {348 Image img = ImageIO.read(new File(imgPath));349 //如果用户输入的图片参数合法则按用户定义的复制,负值参数表示执行默认值350 int newwidth =( width > 0 ) ? width : img.getWidth(null);351 //如果用户输入的图片参数合法则按用户定义的复制,负值参数表示执行默认值352 int newheight = ( height > 0 )? height: img.getHeight(null); 353 //如果是自适应大小则进行比例缩放354 if(autoSize){ 355 // 为等比缩放计算输出的图片宽度及高度356 double Widthrate = ((double) img.getWidth(null)) / (double) width + 0.1;357 double heightrate = ((double) img.getHeight(null))/ (double) height + 0.1;358 double rate = Widthrate > heightrate ? Widthrate : heightrate;359 newwidth = (int) (((double) img.getWidth(null)) / rate);360 newheight = (int) (((double) img.getHeight(null)) / rate);361 }362 //创建目标图像文件363 targetImage = new BufferedImage(newwidth,newheight,BufferedImage.TYPE_INT_RGB);364 Graphics2D g = targetImage.createGraphics();365 g.drawImage(img, 0, 0, newwidth, newheight, null);366 //如果添加水印或者文字则继续下面操作,不添加的话直接返回目标文件----------------------367 g.dispose();368 369 } catch (Exception e) {370 throw new RuntimeException("图片压缩操作异常");371 }372 return targetImage;373 }374 375 376 377 /**378 * 图片黑白化操作(文件物理存盘,使用默认格式)379 * 380 * @param bufferedImage381 * 处理的图片对象382 * @param destPath383 * 目标文件地址384 * @throws Exception 385 *386 */387 public static void imageGray(String imgPath, String destPath)throws Exception{388 imageGray(imgPath, imageFormat(imgPath), destPath);389 }390 391 392 /**393 * 图片黑白化操作(文件物理存盘,可自定义格式)394 * 395 * @param bufferedImage396 * 处理的图片对象397 * @param format398 * 图片格式399 * @param destPath400 * 目标文件地址401 * @throws Exception 402 * 403 */404 public static void imageGray(String imgPath,String format, String destPath)throws Exception{405 try {406 BufferedImage bufferedImage = ImageIO.read(new File(imgPath));407 ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); 408 ColorConvertOp op = new ColorConvertOp(cs, null); 409 bufferedImage = op.filter(bufferedImage, null);410 ImageIO.write(bufferedImage, format , new File(destPath));411 } catch (Exception e) {412 throw new RuntimeException("图片灰白化异常");413 }414 }415 416 417 418 /**419 * 图片透明化操作(文件物理存盘,使用默认格式)420 * 421 * @param imgPath422 * 图片路径423 * @param destPath424 * 图片存放路径425 * @throws Exception426 */427 public static void imageLucency(String imgPath,String destPath)throws Exception{428 try {429 BufferedImage bufferedImage = imageLucency(imgPath);430 ImageIO.write(bufferedImage, imageFormat(imgPath), new File(destPath));431 } catch (Exception e) {432 throw new RuntimeException("图片透明化异常");433 }434 }435 436 437 /**438 * 图片透明化操作(文件物理存盘,可自定义格式)439 * 440 * @param imgPath441 * 图片路径442 * @param format443 * 图片格式444 * @param destPath445 * 图片存放路径446 * @throws Exception447 */448 public static void imageLucency(String imgPath,String format,String destPath)throws Exception{449 try {450 BufferedImage bufferedImage = imageLucency(imgPath);451 ImageIO.write(bufferedImage, format, new File(destPath));452 } catch (Exception e) {453 throw new RuntimeException("图片透明化异常");454 }455 }456 457 /**458 * 图片透明化操作返回BufferedImage对象459 * 460 * @param imgPath461 * 图片路径462 * @return463 * 透明化后的图片对象464 * @throws Exception 465 */466 public static BufferedImage imageLucency(String imgPath)throws Exception{467 BufferedImage targetImage = null;468 try {469 //读取图片 470 BufferedImage img = ImageIO.read(new FileInputStream(imgPath));471 //透明度472 int alpha = 0; 473 //执行透明化474 executeRGB(img, alpha);475 targetImage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);476 Graphics2D g = targetImage.createGraphics();477 g.drawImage(img, 0, 0, null);478 g.dispose();479 } catch (Exception e) {480 throw new RuntimeException("图片透明化执行异常");481 }482 return targetImage;483 }484 485 /**486 * 执行透明化的核心算法487 * 488 * @param img489 * 图片对象490 * @param alpha491 * 透明度492 * @throws Exception 493 */494 public static void executeRGB(BufferedImage img, int alpha) throws Exception{495 int rgb = 0;//RGB值496 //x表示BufferedImage的x坐标,y表示BufferedImage的y坐标497 for(int x=img.getMinX();x> 16 ; 502 int G= (rgb & 0xff00 ) >> 8 ; 503 int B= (rgb & 0xff ); 504 if(((255-R)<30) && ((255-G)<30) && ((255-B)<30)){ 505 rgb = ((alpha + 1) << 24) | (rgb & 0x00ffffff); 506 img.setRGB(x, y, rgb);507 }508 }509 }510 }511 512 513 /**514 * 图片格式转化操作(文件物理存盘)515 * 516 * @param imgPath 517 * 原始图片存放地址518 * @param format519 * 待转换的格式 jpeg,gif,png,bmp等520 * @param destPath521 * 目标文件地址522 * @throws Exception523 */524 public static void formatConvert(String imgPath, String format, String destPath)throws Exception{525 try {526 BufferedImage bufferedImage = ImageIO.read(new File(imgPath));527 ImageIO.write(bufferedImage, format, new File(destPath));528 } catch (IOException e) {529 throw new RuntimeException("文件格式转换出错");530 }531 }532 533 534 535 /**536 * 图片格式转化操作返回BufferedImage对象537 * 538 * @param bufferedImage 539 * BufferedImage图片转换对象540 * @param format541 * 待转换的格式 jpeg,gif,png,bmp等542 * @param destPath543 * 目标文件地址544 * @throws Exception545 */546 public static void formatConvert(BufferedImage bufferedImag, String format, String destPath)throws Exception{547 try {548 ImageIO.write(bufferedImag, format, new File(destPath));549 } catch (IOException e) {550 throw new RuntimeException("文件格式转换出错");551 }552 }553 554 555 /**556 * 获取图片文件的真实格式信息557 * 558 * @param imgPath559 * 图片原文件存放地址560 * @return561 * 图片格式562 * @throws Exception563 */564 public static String imageFormat(String imgPath)throws Exception{565 File file = new File(imgPath);566 String format = ""; //图片格式567 byte[] bt=new byte[(int) file.length()];568 MemoryCacheImageInputStream mcis = new MemoryCacheImageInputStream(new ByteArrayInputStream(bt));569 Iterator it = ImageIO.getImageReaders(mcis);570 while(it.hasNext()){571 ImageReader imgReader = (ImageReader)it.next();572 if(imgReader instanceof GIFImageReader){573 format="gif";574 }else if(imgReader instanceof JPEGImageReader){575 format="jpeg";576 }else if(imgReader instanceof PNGImageReader){577 format="png";578 }else if(imgReader instanceof BMPImageReader){579 format="bmp";580 }581 }582 return format;583 }584 585 }
转载请注明出处[]