【轉】JAVA web 上傳圖片至服務器(本地Linux服務器與Fastdfs)


轉自: http://blog.csdn.net/q908555281/article/details/50456213
 
需求:得到客戶端上傳的圖片--轉化為200尺寸一張。640一張。 加上原圖三張。 
要求:將這三張圖片保存到Linux一份,保存到Fasdfs一份
前提:客戶端(js)圖片壓縮之后,用Base64編碼格式之后上傳過來。
實現:

首先得到圖片的Base64編碼的字符串。轉化成byte[]數組

 

String imgData = request.getParameter( "imgData");// Base64的字符串  
ASE64Decoder decoder = new BASE64Decoder();  
byte[] imgByte = decoder.decodeBuffer(imgData);  
for ( int i = 0; i < imgByte. length; ++i) {  
     if (imgByte[i] < 0) { // 調整異常數據  
         imgByte[i] += 256;  
    }  

首先看本地Linux服務器的:

思路:將圖片的保存地址,以及訪問的路徑保存成一個配置文件。如下,其中fileDir是圖片保存的路徑,host是Linux服務器的主機名,fileStr是 fileDir路徑暴漏出來的訪問連接
#local_development_img_address
fileDir=/data/sites/up/img/
host=http://192.16.1.9
fileStr=/up/img/
 
 
因怕后期圖片過多,導致文件夾里面的文件達到上限,所以在存儲圖片的時候,采用 YYMM/DD文件夾的方式。就是 年月/日,比如2016-01-04.  圖片存儲的路徑則為配置文件中的fileDir+1601/04
所以先得到文件存儲的完整路徑:
     String endFile = DateUtil.  endFileDir(); // 圖片的根目錄后面的文件夾目錄(XXXX/XX(年月)/X(日))
     String imgSavePath =  fileDir + endFile; // 文件完整保存路徑
 
這個endFileDir()的方法代碼如下:

 

 

   /** 
      * 獲得20150803 --> 15/8/3,15/12/6,15/2/15,15/10/3文件夾形式 
      * 
      * @param date 
      * @return 15/10/3文件夾形式 
      */  
     public static String endFileDir () {  
           Date date = new Date(System. currentTimeMillis());  
           SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd" );  
           String str = sdf.format(date).toString();  
           StringBuffer sb = new StringBuffer();  
            char[] timeArr = str.toCharArray();  
           sb = sb.append(timeArr[2]).append(timeArr[3]);  
            // str = ""+timeArr[2]+timeArr[3];  
            if (timeArr[4] != '0') {  
                sb = sb.append(timeArr[4]);  
                 // str+=timeArr[4];  
           }  
           sb = sb.append(timeArr[5]).append( "/");  
            // str+=""+timeArr[5]+"/";//根據當前系統環境確定分隔符  
             
             
            //確定天數作為文件夾,測試部不需要天數,直接注釋即可  
            if(timeArr[6]!= '0'){  
                sb = sb.append(timeArr[6]);  
           }  
           sb = sb.append(timeArr[7]).append( "/");  
            return sb.toString().trim();  
     }  

  這個imgSavePath 就是圖片存儲的完整路徑。

  下一步是圖片的名字: 圖片的名字規則,一般為yyyyMMddHHmmssSSS ,這個就不多說了。
 
  到這一步的時候,我們就可以到到圖片暴漏出來的訪問路徑了。
  路徑為:配置文件中的host+配置文件中的fileStr+endFile+圖片的名字(圖片的名字要包含圖片后綴.png)
  比如:我的圖片的名字為:20160104150412217 ,
  我存儲Linux的文件路徑為:/data/sites/up/img//1601/04/20160104150412217.png
  圖片暴漏出來的訪問路徑為: http://192.16.1.9/up/img/20160104150412217.png
 
 
    然后調用下面的方法存儲到Linux服務器:
 
  /** 
    * @Title: uploadImg 上傳的圖片流 
    * @param path 圖片上傳的路徑 
    * @param fileItem 圖片文件 
    * @return 
    * @return: boolean 
    */  
   private static boolean uploadImg (String path, String imgName, byte[] imgByte) {  
          // Linux服務器是反斜杠  
         path=path.replaceAll( "/", "\\\\");  
         File filePath = new File(path);  
         filePath.setWritable( true, false);  
          if (!filePath.exists()) {  
              filePath.mkdirs();  
         }  
          boolean isSuccess = false;  
         File file = new File(path + imgName);  
         FileOutputStream output = null;  
          try {  
              output = new FileOutputStream(file);  
              output.write(imgByte);  
              output.flush();  
              isSuccess = true;  
         } catch (IOException e) {  
               // TODO Auto-generated catch block  
              e.printStackTrace();  
              isSuccess = false;  
         } finally {  
               try {  
                    if (output != null) {  
                         output.close();  
                   }  
              } catch (IOException e) {  
                    // TODO Auto-generated catch block  
                   e.printStackTrace();  
              }  
         }  
          return isSuccess;  
   }  
存入到FastDfs系統當中
先看一下FastDfs的配置文件:
connect_timeout = 2
network_timeout = 30
charset = UTF-8
http.tracker_http_port = 8080
http.anti_steal_token = no
http.secret_key = FastDFS1234567890
#可以配置多個tracker
tracker_server=172.16.1.9:22122
 
下一步:看代碼,所有的操作都在代碼里面,fastdfs會自動返回一個圖片的訪問路徑,所以不用自己進行路徑的拼接
調用方法:     String imgPath = FastUtil.  uploadImg(imgByte,  IMG_FAST_SEXT );

 

public class FastUtil {  
     private static StorageClient storageClient;  
     private static TrackerServer trackerServer;  
     public static  final String FASTDFS_CONIFG="fdfs_client.conf" ;// Fastdfs的配置文件  
     static {  
            try {  
                 // 初始化Fastdfs  
                String path = new File(FastUtil.class.getResource("/" ).getFile()).getCanonicalPath();  
                String confPath = path + File. separator +FASTDFS_CONIFG;  
                ClientGlobal. init(confPath);  
                TrackerClient tracker = new TrackerClient();  
                 trackerServer = tracker.getConnection();  
                StorageServer storageServer = null;  
                 storageClient = new StorageClient( trackerServer, storageServer);  
           } catch (IOException e) {  
                e.printStackTrace();  
           } catch (MyException e) {  
                e.printStackTrace();  
           }  
     }  
     /** 
      * @Title: uploadImg 
      * @Description:上傳文件到fastdafs服務器 
      * @param fileBuff 文件的字節數組 
      * @param sExt   文件的后綴 
      * @return 
      * @return: String  返回該文件的路徑 
      */  
     public static String uploadImg (byte [] fileBuff, String sExt) {  
           String[] result = null;  
            try {  
                result = storageClient.upload_file(fileBuff, sExt,null);  
           } catch (IOException e) {  
                e.printStackTrace();  
           } catch (MyException e) {  
                e.printStackTrace();  
           }  
            if (result == null) {  
                 return null;  
           } else {  
                String imgPath="http://"+trackerServer .getInetSocketAddress().getHostName()+"/"+result[0]+ "/"+result[1];  
                 return imgPath;  
           }  
     }  
}  

上面,就得到圖片存入到不同的服務器當中的圖片訪問路徑了,下一步將圖片的訪問路徑存入數據庫,這一步操作就不講解了

 
上面說到,還需要一個200尺寸的,一個640尺寸的,調用下面的方法就可以得到圖片相對應的尺寸
/** 
     * @Title: scale 
     * @Description: 將圖片縮放成固定的寬和高 
     * @param imgByte  縮放之后圖片字節數組 
     * @param width 縮放之后的寬度 
     * @param height  高度 
     * @return 
     * @return: byte[] 根據寬高縮放之后的圖片 
     */  
    private static byte[] scale (byte [] imgByte, int w, int h) {  
           byte[] newImgByte = null;  
           try {  
               Image img = ImageIO. read(new ByteArrayInputStream(imgByte));  
                // 根據原圖與要求的縮略圖比例,找到最合適的縮略圖比例  
                int width = img.getWidth( null);  
                int height = img.getHeight( null);  
                if ((width * 1.0) / w < (height * 1.0) / h) {  
                     if (width > w) {  
                          h = Integer. parseInt(new java.text.DecimalFormat("0" ).format(height * w / (width * 1.0)));  
                    }  
               } else {  
                     if (height > h) {  
                          w = Integer. parseInt(new java.text.DecimalFormat("0" ).format(width * h / (height * 1.0)));  
                    }  
               }  
               BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);  
               Graphics g = bi.getGraphics();  
               g.drawImage(img, 0, 0, w, h, null, null);  
               g.dispose();  
               ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  
                if (w == 640) {  
                    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(byteArrayOutputStream);  
                    JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(bi);  
                    jep.setQuality(0.8f, true);  
                    encoder.encode(bi, jep);  
               } else {  
                    ImageIO. write(bi, "PNG", byteArrayOutputStream);  
               }  
               newImgByte = byteArrayOutputStream.toByteArray();  
  
          } catch (IOException e) {  
               e.printStackTrace();  
          }  
           return newImgByte;  
    }  

 



 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM