最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java 使用ImageIO.writer從BufferedImage生成jpeg圖像遇到問(wèn)題總結(jié)及解決

 更新時(shí)間:2017年03月24日 11:03:24   作者:10km  
這篇文章主要介紹了java 使用ImageIO.writer從BufferedImage生成jpeg圖像遇到問(wèn)題總結(jié)及解決的相關(guān)資料,需要的朋友可以參考下

java 使用ImageIO.writer從BufferedImage生成jpeg圖像遇到問(wèn)題總結(jié)及解決

生成jpeg圖像這是個(gè)非常非常簡(jiǎn)單的東西了,網(wǎng)上很多介紹是直接用com.sun.image.codec.jpeg.JPEGImageEncoder來(lái)實(shí)現(xiàn),如下:

  /**
   * 將原圖壓縮生成jpeg格式的數(shù)據(jù)
   * @param source
   * @return
   */
  public static byte[] wirteJPEGBytes(BufferedImage source){
    if(null==source)
      throw new NullPointerException();
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    JPEGImageEncoder jencoder = JPEGCodec.createJPEGEncoder(output);
    JPEGEncodeParam param = jencoder.getDefaultJPEGEncodeParam(source);
    param.setQuality(0.75f, true);
    jencoder.setJPEGEncodeParam(param);
    try {
      jencoder.encode(source);
    } catch (ImageFormatException e) {
      throw new RuntimeException(e);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
    return output.toByteArray();  
  }

JPEGImageEncoder只是sun的jpeg編碼實(shí)現(xiàn),并不是標(biāo)準(zhǔn)的Java API,只在sun jvm中被支持,但在其他的jvm上,并不會(huì)被支持。

而且,雖然上面的代碼在Java 1.6,1.7上都能正常執(zhí)行,但在如果使用java 1.8,上面這個(gè)代碼會(huì)報(bào)錯(cuò):

訪問(wèn)限制:由于對(duì)必需的庫(kù) C:\Program Files\Java\jdk1.8.0_111\jre\lib\rt.jar 具有一定限制,因此無(wú)法訪問(wèn)類型JPEGImageEncoder

這里寫(xiě)圖片描述

所以這個(gè)方法是有局限性的。

走捷徑是不行的,還是得規(guī)規(guī)矩矩按java的規(guī)范來(lái)做,ImageIO類中提供了ImageIO.writer方法可以生成指定的格式的圖像,才是正規(guī)的實(shí)現(xiàn)方式。

但是使用ImageIO.writer方法也是有講究的。

我原先是這樣寫(xiě)的,就是簡(jiǎn)單的調(diào)用ImageIO.writer方法生成jpeg數(shù)據(jù):

  /**
   * 將原圖壓縮生成jpeg格式的數(shù)據(jù)
   * @param source
   * @return
   * @see #wirteBytes(BufferedImage, String)
   */
  public static byte[] wirteJPEGBytes(BufferedImage source){
    return wirteBytes(source,"JPEG");
  }
  /**
   * 將原圖壓縮生成jpeg格式的數(shù)據(jù)
   * @param source
   * @return
   * @see #wirteBytes(BufferedImage, String)
   */
  public static byte[] wirteJPEGBytes(BufferedImage source){
    return wirteBytes(source,"JPEG");
  }
  /**
   * 將{@link BufferedImage}生成formatName指定格式的圖像數(shù)據(jù)
   * @param source
   * @param formatName 圖像格式名,圖像格式名錯(cuò)誤則拋出異常
   * @return
   */
  public static byte[] wirteBytes(BufferedImage source,String formatName){
    Assert.notNull(source, "source");
    Assert.notEmpty(formatName, "formatName");
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    try {      
      if(!ImageIO.write(source, formatName.toLowerCase(), output))
        // 返回false則拋出異常
        throw new IllegalArgumentException(String.format("not found writer for '%s'",formatName));

    } catch (IOException e) {
      throw new RuntimeException(e);
    }
    return output.toByteArray();    
  }

處理了幾萬(wàn)張圖像文件都沒(méi)問(wèn)題,遇到一張png圖像,ImageIO.write居然返回false,拋出異常了。

究其原因,是ImageIO.wite方法在中調(diào)用的私有方法getWriter尋找合適的ImageWriter時(shí)不僅與formatName相關(guān),還是輸入的原圖有關(guān)(具體是怎么相關(guān)的,因?yàn)檫壿嬯P(guān)系太復(fù)雜沒(méi)有深究),造成getWriter方法找不到對(duì)應(yīng)的ImageWriter。

參考網(wǎng)上別人的寫(xiě)法改成這樣就沒(méi)問(wèn)題了:

  /**
   * 將{@link BufferedImage}生成formatName指定格式的圖像數(shù)據(jù)
   * @param source
   * @param formatName 圖像格式名,圖像格式名錯(cuò)誤則拋出異常
   * @return
   */
  public static byte[] wirteBytes(BufferedImage source,String formatName){
    Assert.notNull(source, "source");
    Assert.notEmpty(formatName, "formatName");
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    BufferedImage newBufferedImage = new BufferedImage(source.getWidth(),
        source.getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics2D g = newBufferedImage.createGraphics();
    try {
      g.drawImage(source, 0, 0,null);
      if(!ImageIO.write(newBufferedImage, formatName, output))
        throw new IllegalArgumentException(String.format("not found writer for '%s'",formatName));
    } catch (IOException e) {
      throw new RuntimeException(e);
    }finally{
      g.dispose();
    }
    return output.toByteArray();    
  }

基本的思路就是重創(chuàng)建一個(gè)大小相同的BufferedImage,然后用Graphics.drawImage方法將原圖寫(xiě)入新的BufferedImage對(duì)象,通過(guò)這一道轉(zhuǎn)換,抹平了,不同類型圖像格式生成的BufferedImage對(duì)象之間的區(qū)別,再調(diào)用 ImageIO.write 對(duì)新的ImageIO.write對(duì)象進(jìn)行圖像處理就不會(huì)有問(wèn)題了。

改進(jìn)

在我的項(xiàng)目中圖像數(shù)據(jù)是從互聯(lián)網(wǎng)上搜索到的,遇到的圖像格式絕大部分都是jpeg,但也有少量的png,bmp等格式,對(duì)于占絕大多數(shù)的jpeg圖像來(lái)說(shuō),我最開(kāi)始的方法都是有效的,而上面的這個(gè)方法多出一道工序就顯得有些多余,還浪費(fèi)資源,所以又改進(jìn)了上述的方法,基本的原理就是先嘗試直接ImageIO.write來(lái)生成jpeg,如果失敗,就用第二種方式。

  /**
   * 將{@link BufferedImage}生成formatName指定格式的圖像數(shù)據(jù)
   * @param source
   * @param formatName 圖像格式名,圖像格式名錯(cuò)誤則拋出異常
   * @return
   */
  public static byte[] wirteBytes(BufferedImage source,String formatName){
    Assert.notNull(source, "source");
    Assert.notEmpty(formatName, "formatName");
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    Graphics2D g = null;
    try {
      for(BufferedImage s=source;!ImageIO.write(s, formatName, output);){
        if(null!=g)
          throw new IllegalArgumentException(String.format("not found writer for '%s'",formatName));
        s = new BufferedImage(source.getWidth(),
            source.getHeight(), BufferedImage.TYPE_INT_RGB);
        g = s.createGraphics();
        g.drawImage(source, 0, 0,null);       
      }        
    } catch (IOException e) {
      throw new RuntimeException(e);
    } finally {
      if (null != g)
        g.dispose();
    }
    return output.toByteArray();    
  }

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

  • Java try-with-resource語(yǔ)法使用解析

    Java try-with-resource語(yǔ)法使用解析

    這篇文章主要介紹了Java try-with-resource語(yǔ)法使用解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 用java WebSocket做一個(gè)聊天室

    用java WebSocket做一個(gè)聊天室

    這篇文章主要為大家詳細(xì)介紹了用java WebSocket做一個(gè)聊天室,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Java面試題沖刺第十三天--數(shù)據(jù)庫(kù)(3)

    Java面試題沖刺第十三天--數(shù)據(jù)庫(kù)(3)

    這篇文章主要為大家分享了最有價(jià)值的三道數(shù)據(jù)庫(kù)面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Spring?Boot多個(gè)定時(shí)任務(wù)阻塞問(wèn)題的解決方法

    Spring?Boot多個(gè)定時(shí)任務(wù)阻塞問(wèn)題的解決方法

    在日常的項(xiàng)目開(kāi)發(fā)中,往往會(huì)涉及到一些需要做到定時(shí)執(zhí)行的代碼,下面這篇文章主要給大家介紹了關(guān)于Spring?Boot多個(gè)定時(shí)任務(wù)阻塞問(wèn)題的解決方法,需要的朋友可以參考下
    2022-01-01
  • Java如何判斷字符串中是否包含某個(gè)字符

    Java如何判斷字符串中是否包含某個(gè)字符

    這篇文章主要介紹了Java如何判斷字符串中是否包含某個(gè)字符,可以使用String類的contains()方法,另一種方法使用String類的indexOf方法,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • Java棧之鏈?zhǔn)綏4鎯?chǔ)結(jié)構(gòu)的實(shí)現(xiàn)代碼

    Java棧之鏈?zhǔn)綏4鎯?chǔ)結(jié)構(gòu)的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Java棧之鏈?zhǔn)綏4鎯?chǔ)結(jié)構(gòu)的實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • SpringBoot整合JPA詳細(xì)代碼實(shí)例

    SpringBoot整合JPA詳細(xì)代碼實(shí)例

    這篇文章主要給大家介紹了關(guān)于SpringBoot整合JPA的相關(guān)資料,JPA(Java Persistence API)是Sun官方提出的Java持久化規(guī)范,它為Java開(kāi)發(fā)人員提供了一種對(duì)象/關(guān)聯(lián)映射工具來(lái)管理Java應(yīng)用中的關(guān)系數(shù)據(jù),需要的朋友可以參考下
    2024-05-05
  • 解析java中This的用法分析

    解析java中This的用法分析

    本篇文章是對(duì)java中This的用法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • Java通過(guò)反射機(jī)制動(dòng)態(tài)設(shè)置對(duì)象屬性值的方法

    Java通過(guò)反射機(jī)制動(dòng)態(tài)設(shè)置對(duì)象屬性值的方法

    下面小編就為大家?guī)?lái)一篇Java通過(guò)反射機(jī)制動(dòng)態(tài)設(shè)置對(duì)象屬性值的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-07-07
  • Minio的使用教程

    Minio的使用教程

    Minio是一個(gè)開(kāi)源的對(duì)象存儲(chǔ)服務(wù),兼容Amazon?S3接口,適合存儲(chǔ)大容量非結(jié)構(gòu)化數(shù)據(jù),它部署簡(jiǎn)單,支持海量存儲(chǔ)和分布式部署,通過(guò)配置文件和systemd服務(wù),可以輕松設(shè)置和管理Minio服務(wù),本文介紹Minio的使用教程,感興趣的朋友一起看看吧
    2025-02-02

最新評(píng)論

乌审旗| 普安县| 东海县| 平顶山市| 南阳市| 吴堡县| 威远县| 漠河县| 盘锦市| 同仁县| 雷波县| 昌图县| 麻栗坡县| 会理县| 上饶市| 德令哈市| 华安县| 吴川市| 无为县| 原阳县| 鄂温| 阆中市| 普格县| 吉木乃县| 西华县| 揭西县| 台东市| 孝感市| 阿合奇县| 江北区| 包头市| 恩施市| 老河口市| 五指山市| 景泰县| 兴安盟| 晋州市| 和林格尔县| 图们市| 盘山县| 山丹县|