Jcropを使います.jsとjQuery.form.jsは、ImageIOなどで顔のアップロード・ズームやカットを行います

14588 ワード

まず、JavaコードにImageReaderを取得するIteratorが付いています
    /**
     *       。
     *             ImageReader   Iterator,   ImageReader           。
     *   :postFix -           .(   "jpeg"   "tiff")  。
     * 
     * @param postFix
     *                  
     * @author    
     * @return
     */
    public Iterator<ImageReader> getImageReadersByFormatName(String postFix) {
        switch (postFix) {
        case "jpg":
            return ImageIO.getImageReadersByFormatName("jpg");
        case "jpeg":
            return ImageIO.getImageReadersByFormatName("jpeg");
        case "gif":
            return ImageIO.getImageReadersByFormatName("gif");
        case "bmp":
            return ImageIO.getImageReadersByFormatName("bmp");
        case "png":
            return ImageIO.getImageReadersByFormatName("png");
        default:
            return ImageIO.getImageReadersByFormatName("jpg");
        }
    }

最初のステップはjQueryでform.jsのajaxSubmit()はアップロードした元のピクチャを提出し、ピクチャをスケーリングして等比例サイズのピクチャを返し、返されるピクチャの最大サイズを1000 px X 500 pxに制限する
Javaコアコードは次のとおりです.
	/**
	 * 
	 * imgFileZoom:           ,            
	 * 
	 * @author    
	 * @param postFix
	 * @param in
	 * @param out
	 * @param showHeight         
	 * @param showWidth         
	 * @return
	 * @throws IOException
	 * @since  Ver 1.1
	 */
    public Map<String,String> imgFileZoom(String postFix,InputStream in,FileOutputStream out,int showHeight,int showWidth) throws IOException{
		//FileInputStream is = null;
        ImageInputStream iis = null;
        Map<String,String> map = new HashMap<String,String>();
        try {
            //       
            //is = new FileInputStream(in);

            //         
            
            System.out.println("     :" + postFix);
            /*
             *             ImageReader   Iterator,   ImageReader           。
             *   :formatName -           .(   "jpeg"   "tiff")  。
             */
            Iterator<ImageReader> it = this.getImageReadersByFormatName(postFix);

            ImageReader reader = it.next();
            //      
            iis = ImageIO.createImageInputStream(in);

            /*
             * <p>iis:   .true:      </p>.      ‘     ’。
             *                        ,     reader                             。
             */
            reader.setInput(iis, true);
            int realWidth = reader.getWidth(0);
            int realHeight = reader.getHeight(0);
            
            double ratio = 1.0;
            
            if(realWidth>showWidth){
            	BigDecimal d1 = new BigDecimal(showWidth);
            	BigDecimal d2 = new BigDecimal(realWidth);
            	ratio = d1.divide(d2, 8,BigDecimal.ROUND_HALF_UP).doubleValue();
            }else if(realHeight>showHeight){
            	BigDecimal d1 = new BigDecimal(showHeight);
            	BigDecimal d2 = new BigDecimal(showHeight);
            	ratio = d1.divide(d2, 8,BigDecimal.ROUND_HALF_UP).doubleValue();
            }else{
            	ratio = 1.0;
            }
            
            BigDecimal ratioDecimal = new BigDecimal(ratio);
            BigDecimal realWidthDecimal = new BigDecimal(realWidth);
            BigDecimal realHeightDecimal = new BigDecimal(realHeight);
            BigDecimal outputWidthDecimal = BigDecimal.ONE;
            BigDecimal outputHeightDecimal = BigDecimal.ONE;
            outputWidthDecimal = realWidthDecimal.multiply(ratioDecimal);
            outputHeightDecimal = realHeightDecimal.multiply(ratioDecimal);
            int outputWidth = outputWidthDecimal.intValue();
            int outputHeight = outputHeightDecimal.intValue();
            //             
            map.put("outputWidth", String.valueOf(outputWidth));
            map.put("outputHeight", String.valueOf(outputHeight));
            
            /*
             *        ImageReadParam        imageIndex      ,           
             * BufferedImage   。
             */
            BufferedImage bi = reader.read(0);

            
            /*
             *     
             */
            Image imageSmall = bi.getScaledInstance(outputWidth, outputHeight, Image.SCALE_DEFAULT);  
            
            BufferedImage small = new BufferedImage(outputWidth, outputHeight, BufferedImage.TYPE_INT_RGB);
            
            Graphics g = small.getGraphics();
            g.drawImage(imageSmall, 0, 0, null); //           Image   BufferedImage 
            g.dispose();
            
            
            
            //         
            ImageIO.write(small, postFix, out);
        } finally {
            if (in != null)
                in.close();
            if (iis != null)
                iis.close();
            if (out != null)
                out.close();
        }
        return map;
    }
    
    /**
     * 
     * updateZoomTxService:            ,       
     * 
     * @author    
     * @param pic
     * @param req
     * @return
     * @since  Ver 1.1
     */
    public Map<String,Object> uploadZoomTx(MultipartFile pic,String uid,HttpServletRequest req){
		// CommonInfo          
		String pathString = CommonInfo.touxiangPath+"/zoom/";
		String fileName = "";
		Map<String,Object> map = new HashMap<String,Object>();
		
		//            
		if (pic.getSize() > 0) {
			//user.setImage(pathString + pic.getOriginalFilename());
			//            
			File file = new File(pathString);

			if (!file.exists() && !file.isDirectory()) {
				file.mkdirs();
			}
			try {
				String ext=pic.getOriginalFilename().substring(pic.getOriginalFilename().lastIndexOf(".")+1,pic.getOriginalFilename().length());
				fileName = System.currentTimeMillis()+uid+"."+ext;
				//           
				FileOutputStream fout = new FileOutputStream(pathString + fileName );
				
				
				map.put("imgInfo",this.imgFileZoom(ext.toLowerCase(),pic.getInputStream(),fout,500,1000));
				map.put("imgUrl", fileName);
				
				if(fout!=null) 
					fout.close();
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return map;
	}

返されるパラメータには、ズーム後の画像の長さと幅の情報があり、フロントjsで取得され、Jcropを初期化します.
フロントコアコード(ajaxSubmit()および成功後のトリガ):
		$("#uploadTxBtn").click(function(){
			var option = {  
                    type: "post",  
                    success : function(data){  
                    	zoomPicName = data['imgUrl'];
                       
                       $("#p_img").attr("src", "../../touxiang/zoom/"+data['imgUrl']);
                       $("#p_img").show();
                       $("#preview_block").show();
                       $("#p_img_preview").attr("src", "../../touxiang/zoom/"+data['imgUrl']);
                       $("#p_img").width(data['imgInfo']['outputWidth']);
                       $("#p_img").height(data['imgInfo']['outputHeight']);
                       
                       $("#uploadZoomTx").height(parseInt(data['imgInfo']['outputHeight'])+150);
                       caijian();
                   }  
                  };  
                  $("#uploadZoomTx").ajaxSubmit(option);  
		});

Jcrop関連初期化のjsコード:
function caijian(){

        
        
  // Create variables (in this scope) to hold the API and image size
  var jcrop_api, boundx, boundy;
  
  $('#p_img').Jcrop({
    onChange: updatePreview,
    onSelect: updatePreview,
    aspectRatio: 1,
    setSelect: [0,0,100,100]
  },function(){
    // Use the API to get the real image size
    var bounds = this.getBounds();
    boundx = bounds[0];
    boundy = bounds[1];
    
    console.log(1111);
    console.log(bounds);
    
    
    // Store the API in the jcrop_api variable
    jcrop_api = this;
  });

  function updatePreview(c)
  {
    if (parseInt(c.w) > 0)
    {
    	
    	
    	console.log(c);
    	img_x = c.x;
    	img_y = c.y;
    	img_w = c.w;
    	img_h = c.h;
    
		
      var rx = 100 / c.w;
      var ry = 100 / c.h;

      $('#p_img_preview').css({
        width: Math.round(rx * boundx) + 'px',
        height: Math.round(ry * boundy) + 'px',
        marginLeft: '-' + Math.round(rx * c.x) + 'px',
        marginTop: '-' + Math.round(ry * c.y) + 'px'
      });
      

    }
  };
}

ステップ2:
ユーザはトリミングボックスをドラッグして終了し、トリミングボタンをクリックした後、開始点の横縦座標とトリミング領域の幅の高さの4つのパラメータをアップロードします.
今回のプロセスではパラメータのみがアップロードされ、画像はアップロードされず、バックグラウンドではパラメータに基づいて前のステップでスケールした画像を再び切り取り、スケールします.
jsコードは省略し、バックグラウンドJavaコアコードは以下の通りである.
	/**
	 * 
	 * imgFileCut:           ,            
	 * 
	 * @author    
	 * @param postFix
	 * @param in
	 * @param out
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 * @param showHeight
	 * @param showWidth
	 * @throws IOException
	 * @since  Ver 1.1
	 */
    public void imgFileCut(String postFix,InputStream in,FileOutputStream out,int x,int y,int width,int height) throws IOException{
        ImageInputStream iis = null;
        try {

            /*
             *             ImageReader   Iterator,   ImageReader           。
             *   :formatName -           .(   "jpeg"   "tiff")  。
             */
            Iterator<ImageReader> it = getImageReadersByFormatName(postFix);

            ImageReader reader = it.next();
            //      
            iis = ImageIO.createImageInputStream(in);

            /*
             * <p>iis:   .true:      </p>.      ‘     ’。
             *                        ,     reader                             。
             */
            reader.setInput(iis, true);
            
            /*
             * <p>            <p>.            Java Image I/O
             *                     。                ImageReader    
             * getDefaultReadParam       ImageReadParam    。
             */
            ImageReadParam param = reader.getDefaultReadParam();

            /*
             *       。Rectangle              ,   Rectangle   
             *         (x,y)、             。
             */
            Rectangle rect = new Rectangle(x, y, width, height);

            //      BufferedImage,             。
            param.setSourceRegion(rect);
            
            /*
             *        ImageReadParam        imageIndex      ,           
             * BufferedImage   。
             */
            BufferedImage bi = reader.read(0, param);
            
            
            
            /* 
             *      
             */  
            Image imageSmall = bi.getScaledInstance(100, 100, Image.SCALE_DEFAULT);    
              
            BufferedImage small = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);  
              
            Graphics g = small.getGraphics();  
            g.drawImage(imageSmall, 0, 0, null); //           Image   BufferedImage   
            g.dispose();  
            
            
            
            //      
            ImageIO.write(small, postFix, out);
        } finally {
            if (in != null)
                in.close();
            if (iis != null)
                iis.close();
            if (out != null)
                out.close();
        }
    }
    
	public String saveTx(String zoomedImageName, String img_x, String img_y,
			String img_w, String img_h) {
		String zoomedImagePath = CommonInfo.touxiangPath+"/zoom/"+zoomedImageName;
		String finalImagePath = CommonInfo.touxiangPath+zoomedImageName;
		File zoomedImagefile = new File(zoomedImagePath);
		try {
			InputStream in = new FileInputStream(zoomedImagefile);
			File finalImage = new File(finalImagePath);
			FileOutputStream out = new FileOutputStream(finalImage);
			int x = new BigDecimal(img_x).intValue();
			int y = new BigDecimal(img_y).intValue();
			int w = new BigDecimal(img_w).intValue();
			int h = new BigDecimal(img_h).intValue();
			String postFix=zoomedImageName.substring(zoomedImageName.lastIndexOf(".")+1,zoomedImageName.length()).toLowerCase();
			this.imgFileCut(postFix, in, out, x, y, w, h);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("      ");
			return "error";
		}
		return "success";
	}

Controlでの主な呼び出し方法:
	/**
	 * 
	 * updateZoomTx:               ,           
	 * 
	 * @author    
	 * @param pic
	 * @param req
	 * @return
	 * @since  Ver 1.1
	 */
	@ResponseBody
	@RequestMapping(value = "/uploadZoomTx.do")
	public Map<String,Object> updateZoomTx(MultipartFile pic,HttpServletRequest req){
		Map<String,Object> map = null;
		if(req.getSession()!=null&&req.getSession().getAttribute("curruser")!=null){
			String uid = "";
			uid = ((User)(req.getSession().getAttribute("curruser"))).getId();
			map =userService.uploadZoomTx(pic,uid,req);
		}else{
			map=new HashMap<String,Object>();
			map.put("error","error");
		}
		return map;
	}
	
	/**
	 * 
	 * saveTx:                  ,      
	 * 
	 * @author    
	 * @param zoomedImageName
	 * @param img_x
	 * @param img_y
	 * @param img_w
	 * @param img_h
	 * @param req
	 * @return
	 * @since  Ver 1.1
	 */
	@ResponseBody
	@RequestMapping(value = "/saveTx.do")
	public String saveTx(String zoomedImageName,String img_x,String img_y,String img_w,String img_h,HttpServletRequest req){
		String re =userService.saveTx( zoomedImageName,img_x, img_y, img_w, img_h);
		if(req.getSession()!=null&&req.getSession().getAttribute("curruser")!=null){
			User user = (User)(req.getSession().getAttribute("curruser"));
			user.setImage(zoomedImageName);
			userService.saveOrUpdate(user);
			return "ok";
		}else{
			return "error";
		}
	}

HTML 5のcanvasやflashを利用して切り取ることについても考えていますが、互換性を考えると、まずそうしましょう.
関連資源:http://download.csdn.net/detail/lgh06/8343359ポイントフリー
プレビュー効果:
本文はブロガーのオリジナル文章で、ブロガーの許可を得ずに転載してはならない.