逻辑梳理:

1、根据图片切割出来小图片,原图片小图片部分加阴影。

2、阴影图片和切割后图片传给前台

3、前段确定用户图片拖动长度

4、这里产生分歧,长度验证是传回后端验证,还是直接在前段处理。

 

无论如何,业务逻辑不谈,核心是要存在工具切割图片达到效果,这里展示下我的工具。

一、ImageUtils   cut方法即为切割逻辑

package com.cloudwise.util;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

import sun.misc.BASE64Encoder;

public class ImageUtils {

	/**
     * jpg图片格式
     */
    private static final String IMAGE_FORM_OF_JPG = "jpg";
    /**
     * png图片格式
     */
    private static final String IMAGE_FORM_OF_PNG = "png";

    /**
     * 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader 声称能够解码指定格式。
     * 参数:formatName - 包含非正式格式名称 .(例如 "jpeg" 或 "tiff")等 。
     * 
     * @param postFix
     *            文件的后缀名
     * @return
     */
    public static Iterator<ImageReader> getImageReadersByFormatName(String postFix) {
        switch (postFix) {
        case IMAGE_FORM_OF_JPG:
            return ImageIO.getImageReadersByFormatName(IMAGE_FORM_OF_JPG);
        case IMAGE_FORM_OF_PNG:
            return ImageIO.getImageReadersByFormatName(IMAGE_FORM_OF_PNG);
        default:
            return ImageIO.getImageReadersByFormatName(IMAGE_FORM_OF_JPG);
        }
    }
 
    /**
     * 对图片裁剪,并把裁剪完de新图片保存 。
     * @param srcpath 源图片路径
     * @param subpath 剪切图片存放路径
     * @throws IOException
     */
    public static Map<String,String> cut(ImageCutParam param1) throws IOException {
        FileInputStream is = null;
        ImageInputStream iis = null;
        try {
            // 读取图片文件
            is = new FileInputStream(param1.getResourcePath());
            // 获取文件的后缀名
            String postFix = getPostfix(param1.getResourcePath());
            System.out.println("图片格式为:" + postFix);
            /*
             * 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader 声称能够解码指定格式。
             * 参数:formatName - 包含非正式格式名称 .(例如 "jpeg" 或 "tiff")等 。
             */
            Iterator<ImageReader> it = getImageReadersByFormatName(postFix);
 
            ImageReader reader = it.next();
            // 获取图片流
            iis = ImageIO.createImageInputStream(is);
 
            /*
             * <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(param1.getX(), param1.getY(), param1.getW(), param1.getH());
 
            // 提供一个 BufferedImage,将其用作解码像素数据的目标。
            param.setSourceRegion(rect);
            /*
             * 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象,并将 它作为一个完整的
             * BufferedImage 返回。
             */
            BufferedImage bi = reader.read(0, param);
            
            ByteArrayOutputStream CatBaos = new ByteArrayOutputStream();//io流
            ImageIO.write(bi, postFix, CatBaos);//写入流中
            byte[] CutBytes = CatBaos.toByteArray();//转换成字节

            BASE64Encoder encoder = new BASE64Encoder();
            String CutPng_base64 =  encoder.encodeBuffer(CutBytes).trim();//转换成base64串
            CutPng_base64 = CutPng_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
 
//            String path = subpath + "_" + new Date().getTime() + "." + postFix;
//            
            File file = new File(param1.getTargetPath()+"\\"+new Date().getTime()+"."+postFix);
    		File fileParent = file.getParentFile();
    		if(!fileParent.exists()){
    			System.out.println("自动创建文件");
    			fileParent.mkdirs(); 
    		} 
    			file.createNewFile();
            // 保存新图片
            ImageIO.write(bi, postFix, file);
            
            
          /*********************************************************************************/
		    
		    /*************************生成数组*************************/
            BufferedImage sourceImg = ImageIO.read(new FileInputStream(param1.getResourcePath()));
		    int[][] data = new int[sourceImg.getWidth()][sourceImg.getHeight()];
		    for (int i=0;i<sourceImg.getWidth();i++){//1280
		    	for(int j=0;j<sourceImg.getHeight();j++){//720
		    		if(i< param1.getX() +200 && i >= param1.getX() && j < param1.getY() + 120 && j > param1.getY()){
		    			data[i][j]=1;
		    		}else {
		    			data[i][j]=0;
		    		}
		    	}
		    }
		    /*********************************************************/
		    
		    /************************图片局部变黑************************/
		    for (int i = 0; i < sourceImg.getWidth(); i++) {
		    	for (int j = 0; j < sourceImg.getHeight(); j++) {
		    		int rgb = data[i][j];
		    		// 原图中对应位置变色处理
		    		
		    		int rgb_ori = sourceImg.getRGB(i,  j);
		    		
		    		if (rgb == 1) {
		    			//颜色处理
		    			int r = (0XFF000000 & rgb_ori);
		    			int g = (0XFF000000 & (rgb_ori >> 8));
		    			int b = (0XFF000000 & (rgb_ori >> 16));
		    			int Gray = (r*2 + g*5 + b*1) >> 3;
		    			
		    			//原图对应位置颜色变化
		    			sourceImg.setRGB(i, j, Gray);
		    		}
		    	}
		    }
		    /**********************************************************/
		    
		    /************************阴影图片转base64************************/
		    //BASE64Encoder encoder = new BASE64Encoder();
		    ByteArrayOutputStream YYbaos = new ByteArrayOutputStream();//io流
	        ImageIO.write(sourceImg, postFix, YYbaos);//写入流中
	        byte[] bytes = YYbaos.toByteArray();//转换成字节
	        String YYPng_base64 =  encoder.encodeBuffer(bytes).trim();//转换成base64串
	        YYPng_base64 = YYPng_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
	        
	        FileOutputStream fos = new FileOutputStream(
	        		new File(param1.getTargetPath()+"\\"+new Date().getTime()+"." +postFix));
		    BufferedOutputStream bos = new BufferedOutputStream(fos);
		    bos.write(bytes);
            
		    
		    Map<String, String> map = new HashMap<String,String>();
		    
		    map.put("x", param1.getX()+"");					//裁剪开始X坐标
		    map.put("y", param1.getY()+"");					//裁剪开始Y坐标
		    map.put("backGroud", YYPng_base64);	//阴影图片base
		    map.put("cutImg", CutPng_base64);//裁剪图片base
            return map;
        } finally {
            if (is != null)
                is.close();
            if (iis != null)
                iis.close();
        }
 
    }
 
    /**
     * 获取inputFilePath的后缀名,如:"e:/test.pptx"的后缀名为:"pptx"<br>
     * 
     * @param inputFilePath
     * @return
     */
    public static String getPostfix(String inputFilePath) {
        return inputFilePath.substring(inputFilePath.lastIndexOf(".") + 1);
    }
    
}

2、上面需要的参数类ImageCutParam

package com.cloudwise.util;

import java.util.Random;

public class ImageCutParam {

	/**
	 * 代表背景图片的长和宽
	 */
	private final static int Image_Width = 700;
	private final static int Image_Height = 480;
	

	/**
	 * 在被裁剪的图上的裁剪位置的x
	 */
	private int x;
	/**
	 *在被裁剪的图上的裁剪位置的y
	 */
	private int y;
	/**
	 * 要裁剪出来的图片的长
	 */
	private int w = 200;
	/**
	 * 要裁剪出来的图片的宽
	 */
	private int h = 120;
	
	private String resourcePath;
	private String targetPath = "D:\\aimg";
	
	
	
	
	public ImageCutParam() {}

	public ImageCutParam(String resourcePath) {
		super();
		Random rand = new Random();
		int ImgIndex = rand.nextInt(5) +1; //生成0-6以内的随机数
		int x = rand.nextInt(ImageCutParam.Image_Width); //生成0-700以内的随机数
		int y = rand.nextInt(ImageCutParam.Image_Height); //生成0-480以内的随机数
		if(x < this.getW()){
			x = x + 200;
		}
		if(x > ImageCutParam.Image_Width-this.getW()){
			x = x-this.getW();
		}
		if(y > ImageCutParam.Image_Height - this.getH()){
			y = y -this.getH();
		}
		this.x = x;
		this.y = y;
		this.resourcePath = resourcePath;
	}


	public ImageCutParam(int x, int y, int w, int h, String resourcePath, String targetPath) {
		super();
		this.x = x;
		this.y = y;
		this.w = w;
		this.h = h;
		this.resourcePath = resourcePath;
		this.targetPath = targetPath;
	}


	public int getX() {
		return x;
	}


	public void setX(int x) {
		this.x = x;
	}


	public int getY() {
		return y;
	}


	public void setY(int y) {
		this.y = y;
	}


	public int getW() {
		return w;
	}


	public void setW(int w) {
		this.w = w;
	}


	public int getH() {
		return h;
	}


	public void setH(int h) {
		this.h = h;
	}


	public String getResourcePath() {
		return resourcePath;
	}


	public void setResourcePath(String resourcePath) {
		this.resourcePath = resourcePath;
	}


	public String getTargetPath() {
		return targetPath;
	}


	public void setTargetPath(String targetPath) {
		this.targetPath = targetPath;
	}
	
	
}

三、使用例子

package com.cloudwise.latch;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import javax.imageio.ImageIO;

import com.cloudwise.util.ImageCutParam;
import com.cloudwise.util.ImageUtils;

public class Test {

	public static void main(String[] args) throws IOException {
		
		
			Map<Object,Object> map = new HashMap<Object,Object>();
			ImageCutParam param = new ImageCutParam("D:\\aimg\\timg.jpg");
			
		    Map<String,String> map1 = ImageUtils.cut(param);
		    
		    map1.forEach((k,v) -> {
		    	System.out.println("key : "+ k +" , value : " + v);
		    });
		}
}

最后只展示下切割后的图片:

java easyexcel 浮动图片 用java实现图片滑动_java