网络传输过程中,为什么要对图像和视频流进行压缩
第一,压缩的必要性:
图象和视频通常在计算机中表示后会占用非常大的空间,而出于节省硬盘空间的考虑,往往要进行压缩。同时,传输过程中,为了节省珍贵的带宽资源和节省时间,也迫切要求压缩。压缩之后,传输过程中的误码率也会相应地减少。
第二,压缩的可能性:
人眼对颜色只有一定的感应能力,当某些颜色十分相近时,人是感觉不出差异的(或者很小)。这一点为压缩提供了机会。我们把相近的颜色用一种颜色表示,从而减少了图象的存储空间,实现压缩。同时,通过解压缩,我们可以根据之前采取的压缩方法(有损压缩、无损压缩等)进行相应的解压缩措施,保证图象的真度恢复。
下面是个人封装的工具,具有用户自定义图片压缩水印(图片水印,文字水印)、图片透明处理、灰白处理、格式获取、格式转换、物理存储、处理中介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 : 苏若年 <a href="mailto:[email protected]">发送邮件</a> 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 imgPath 109 * 待处理图片 110 * @param markPath 111 * 水印图片 112 * @param x 113 * 水印位于图片左上角的 x 坐标值 114 * @param y 115 * 水印位于图片左上角的 y 坐标值 116 * @param alpha 117 * 水印透明度 0.1f ~ 1.0f 118 * @return
119 * 处理后的图片对象 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 imgPath 153 * 待处理图片 154 * @param text 155 * 水印文字 156 * @param font 157 * 水印字体信息 不写默认值为宋体 158 * @param color 159 * 水印字体颜色 160 * @param x 161 * 水印位于图片左上角的 x 坐标值 162 * @param y 163 * 水印位于图片左上角的 y 坐标值 164 * @param alpha 165 * 水印透明度 0.1f ~ 1.0f 166 * @param format 167 * 添加水印后存储的格式 168 * @param destPath 169 * 文件存放路径 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 imgPath 186 * 待处理图片 187 * @param text 188 * 水印文字 189 * @param font 190 * 水印字体信息 不写默认值为宋体 191 * @param color 192 * 水印字体颜色 193 * @param x 194 * 水印位于图片左上角的 x 坐标值 195 * @param y 196 * 水印位于图片左上角的 y 坐标值 197 * @param alpha 198 * 水印透明度 0.1f ~ 1.0f 199 * @param format 200 * 添加水印后存储的格式 201 * @param destPath 202 * 文件存放路径 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 imgPath 219 * 待处理图片 220 * @param text 221 * 水印文字 222 * @param font 223 * 水印字体信息 不写默认值为宋体 224 * @param color 225 * 水印字体颜色 226 * @param x 227 * 水印位于图片左上角的 x 坐标值 228 * @param y 229 * 水印位于图片左上角的 y 坐标值 230 * @param alpha 231 * 水印透明度 0.1f ~ 1.0f 232 * @return
233 * 处理后的图片对象 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 imgPath 266 * 待处理图片 267 * @param quality 268 * 图片质量(0-1之間的float值) 269 * @param width 270 * 输出图片的宽度 输入负数参数表示用原来图片宽 271 * @param height 272 * 输出图片的高度 输入负数参数表示用原来图片高 273 * @param autoSize 274 * 是否等比缩放 true表示进行等比缩放 false表示不进行等比缩放 275 * @param format 276 * 压缩后存储的格式 277 * @param destPath 278 * 文件存放路径 279 * 280 * @throws Exception 281 */
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 imgPath 298 * 待处理图片 299 * @param quality 300 * 图片质量(0-1之間的float值) 301 * @param width 302 * 输出图片的宽度 输入负数参数表示用原来图片宽 303 * @param height 304 * 输出图片的高度 输入负数参数表示用原来图片高 305 * @param autoSize 306 * 是否等比缩放 true表示进行等比缩放 false表示不进行等比缩放 307 * @param format 308 * 压缩后存储的格式 309 * @param destPath 310 * 文件存放路径 311 * 312 * @throws Exception 313 */
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 imgPath 329 * 待处理图片 330 * @param quality 331 * 图片质量(0-1之間的float值) 332 * @param width 333 * 输出图片的宽度 输入负数参数表示用原来图片宽 334 * @param height 335 * 输出图片的高度 输入负数参数表示用原来图片高 336 * @param autoSize 337 * 是否等比缩放 true表示进行等比缩放 false表示不进行等比缩放 338 * @return
339 * 处理后的图片对象 340 * @throws Exception 341 */
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 bufferedImage 381 * 处理的图片对象 382 * @param destPath 383 * 目标文件地址 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 bufferedImage 396 * 处理的图片对象 397 * @param format 398 * 图片格式 399 * @param destPath 400 * 目标文件地址 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 imgPath 422 * 图片路径 423 * @param destPath 424 * 图片存放路径 425 * @throws Exception 426 */
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 imgPath 441 * 图片路径 442 * @param format 443 * 图片格式 444 * @param destPath 445 * 图片存放路径 446 * @throws Exception 447 */
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 imgPath 461 * 图片路径 462 * @return
463 * 透明化后的图片对象 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 img 489 * 图片对象 490 * @param alpha 491 * 透明度 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<img.getWidth();x++){ 498 for(int y=img.getMinY();y<img.getHeight();y++){ 499 //获取点位的RGB值进行比较重新设定
500 rgb = img.getRGB(x, y); 501 int R =(rgb & 0xff0000 ) >> 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 format 519 * 待转换的格式 jpeg,gif,png,bmp等 520 * @param destPath 521 * 目标文件地址 522 * @throws Exception 523 */
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 format 541 * 待转换的格式 jpeg,gif,png,bmp等 542 * @param destPath 543 * 目标文件地址 544 * @throws Exception 545 */
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 imgPath 559 * 图片原文件存放地址 560 * @return
561 * 图片格式 562 * @throws Exception 563 */
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<ImageReader> 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 }
转载请注明出处[http://www.cnblogs.com/dennisit/archive/2012/12/28/2837452.html]