Java Image Tool class instance based on Decorator Pattern [With demo source code download]

  • 2020-10-23 20:58:29
  • OfStack

This article gives an example of Java's image utility class based on decorator pattern. To share for your reference, the details are as follows:

ImgUtil. java:


/*
 *  Decorator pattern implements the image processing tool class 
 *  similar java the io flow  - 
 * Img Similar low-level streams can be used independently 
 * Press and Resize Similar high level flow 
 *  Need to depend on the lower stream 
 */
package util;
import java.io.File;
import java.util.List;
/**
 *  Picture tool class ( decorator ) And pictures ( Be decorator ) Public interface 
 * @author xlk
 */
public interface ImgUtil {
  /**  Adornment method  -  Processing images  */
  List<File> dispose();
}

AbstractImgUtil. java:


package util;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
/**
 *  Abstract image tool class  -  Abstract decorator 
 * @author xlk
 */
public abstract class AbstractImgUtil implements ImgUtil {
  private ImgUtil imgUtil;
  @Override
  public List<File> dispose() {
    return imgUtil.dispose();
  }
  public AbstractImgUtil(){}
  public AbstractImgUtil(ImgUtil imgUtil) {
    this.imgUtil = imgUtil;
  }
  /**
   *  Determine if the file is an image 
   * @param file  The judged document 
   * @return  Photos back true  Non-image return false
   * @throws IOException 
   */
  public static boolean isImg(File file) {
    if (file.isDirectory()) {
      return false;
    }
    try {
      ImageInputStream iis = ImageIO.createImageInputStream(file);
      Iterator<ImageReader> iter = ImageIO.getImageReaders(iis);
      if (!iter.hasNext()) {// A file is not a picture 
        return false;
      }
      return true;
    } catch (IOException e) {
      return false;
    }
  }
}

Press. java:


package util;
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
/**
 *  watermarking  -  decorator 
 * @author xlk
 */
public class Press extends AbstractImgUtil {
  private  List<File>  src;   // Picture path set 
  private  String    waterImg;// Watermark image path 
  private  Integer    x;     // The offset to the left of the watermark image from the target image ,  if x<0,  It's right in the middle 
  private  Integer    y;     // The offset of the watermark image from the top of the target image ,  if y<0,  It's right in the middle 
  private  float    alpha;   // Watermark transparency (0.0 -- 1.0, 0.0 To be completely transparent, 1.0 Is completely opaque )
  @Override
  public List<File> dispose() {
    src = super.dispose();
    return press();
  }
  /**  watermarking  -  Specific decoration method  */
  private List<File> press() {
    if (waterImg==null || "".equals(waterImg)) {
      throw new RuntimeException(" The watermark path cannot be empty ");
    }
    if (!isImg(new File(waterImg))) {
      throw new RuntimeException(" The watermark path points to a file that is not an image ");
    }
    if (src.size()<=0) {
      return src;
    }
    if (x!=null && y!=null) {
      for (File f: src) {
        press(f.getPath(), waterImg, f.getParent(), x, y, alpha);
      }
    } else {
      for (File f: src) {
        press(f.getPath(), waterImg, f.getParent(), alpha);
      }
    }
    return src;
  }
  public Press() {}
  public Press(ImgUtil imgUtil, String waterImg, float alpha) {
    super(imgUtil);
    this.waterImg = waterImg;
    this.alpha = alpha;
  }
  public Press(ImgUtil imgUtil, String waterImg, Integer x, Integer y, float alpha) {
    super(imgUtil);
    this.waterImg = waterImg;
    this.x = x;
    this.y = y;
    this.alpha = alpha;
  }
  public String getWaterImg() {
    return waterImg;
  }
  public void setWaterImg(String waterImg) {
    this.waterImg = waterImg;
  }
  public Integer getX() {
    return x;
  }
  public void setX(Integer x) {
    this.x = x;
  }
  public Integer getY() {
    return y;
  }
  public void setY(Integer y) {
    this.y = y;
  }
  public float getAlpha() {
    return alpha;
  }
  public void setAlpha(float alpha) {
    this.alpha = alpha;
  }
  /**  Add image watermark  */
  private static void press(String src, String waterImg, String target, int x, int y, float alpha) {
    File newFile = null;
    try {
      File file = new File(src);
      Image image = ImageIO.read(file);
      int width = image.getWidth(null);
      int height = image.getHeight(null);
      BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
      Graphics2D g = bufferedImage.createGraphics();
      g.drawImage(image, 0, 0, width, height, null);
      
      Image waterImage = ImageIO.read(new File(waterImg)); //  Watermark file 
      int width_1 = waterImage.getWidth(null);
      int height_1 = waterImage.getHeight(null);
      g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
      
      int widthDiff = width - width_1;
      int heightDiff = height - height_1;
      if (x < 0) {
        x = widthDiff / 2;
      } else if (x > widthDiff) {
        x = widthDiff;
      }
      if (y < 0) {
        y = heightDiff / 2;
      } else if (y > heightDiff) {
        y = heightDiff;
      }
      g.drawImage(waterImage, x, y, width_1, height_1, null); //  End of watermark file 
      g.dispose();
      
      File dir = new File(target);
      if (!dir.exists()) {
        dir.mkdirs();
      }
      newFile = new File(target + File.separator + file.getName());
      ImageIO.write(bufferedImage, "jpg", newFile);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  /**  Tile to add image watermark  */
  private static void press(String src, String waterImg, String target, float alpha) {
    File newFile = null;
    try {
      File file = new File(src);
      Image image = ImageIO.read(file);
      int width = image.getWidth(null);
      int height = image.getHeight(null);
      BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
      Graphics2D g = bufferedImage.createGraphics();
      g.drawImage(image, 0, 0, width, height, null);
      
      Image waterImage = ImageIO.read(new File(waterImg)); //  Watermark file 
      int width_1 = waterImage.getWidth(null);
      int height_1 = waterImage.getHeight(null);
      g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
      
      int rpt_x = width>width_1?(int)Math.ceil(Double.valueOf(width)/width_1):1;//x Number of directional repeats 
      int rpt_y = height>height_1?(int)Math.ceil(Double.valueOf(height)/height_1):1;//y Number of directional repeats 
      for (int i=0; i<rpt_x; i++) {
        for (int j=0; j<rpt_y; j++) {
          g.drawImage(waterImage, i*width_1, j*height_1, width_1, height_1, null);
        }
      }//  End of watermark file 
      g.dispose();
      
      File dir = new File(target);
      if (!dir.exists()) {
        dir.mkdirs();
      }
      newFile = new File(target + File.separator + file.getName());
      ImageIO.write(bufferedImage, "jpg", newFile);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

Resize. java:


package util;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
/**
 *  The zoom  -  decorator 
 * @author xlk
 */
public class Resize extends AbstractImgUtil {
  /**  Scale different boundary colors  */
  private static final Color color = new Color(230,230,230);
  private  List<File>  src;  // Picture path set 
  private  int      height;  // Post-treatment height 
  private int      width;  // Processed width 
  private double    ratio;  // After treatment, aspect ratio 
  private boolean    bb;    // Whether to fill when the proportion is wrong 
  @Override
  public List<File> dispose() {
    src = super.dispose();
    return resize();
  }
  /**  The zoom  -  Specific decoration method  */
  private List<File> resize() {
    if (src.size()<=0) {
      return src;
    }
    if (ratio>0) {
      for (File f: src) {
        resize(f.getPath(), f.getParent(), ratio, bb);
      }
    } else if (height>0 && width>0) {
      for (File f: src) {
        resize(f.getPath(), f.getParent(), height, width, bb);
      }
    }
    return src;
  }
  public Resize() {}
  public Resize(ImgUtil imgUtil, int height, int width, boolean bb) {
    super(imgUtil);
    this.height = height;
    this.width = width;
    this.bb = bb;
  }
  public Resize(ImgUtil imgUtil, double ratio, boolean bb) {
    super(imgUtil);
    this.ratio = ratio;
    this.bb = bb;
  }
  public int getHeight() {
    return height;
  }
  public void setHeight(int height) {
    this.height = height;
  }
  public int getWidth() {
    return width;
  }
  public void setWidth(int width) {
    this.width = width;
  }
  public double getRatio() {
    return ratio;
  }
  public void setRatio(double ratio) {
    this.ratio = ratio;
  }
  public boolean isBb() {
    return bb;
  }
  public void setBb(boolean bb) {
    this.bb = bb;
  }
  /**  zooming - According to the size  */
  private static void resize(String src, String target, int height, int width, boolean bb) {
    File newFile = null;
    try {
      double ratio = 0; // scaling 
      File f = new File(src);
      BufferedImage bi = ImageIO.read(f);
      Image itemp = bi.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH);
      // Calculate percentage 
      if (Double.valueOf(bi.getHeight())/bi.getWidth() > Double.valueOf(height)/width) {
        ratio = Double.valueOf(height) / bi.getHeight();
      } else {
        ratio = Double.valueOf(width) / bi.getWidth();
      }
      AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);
      itemp = op.filter(bi, null);
      if (bb) {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();
        g.setColor(color);
        g.fillRect(0, 0, width, height);
        if (width == itemp.getWidth(null))
          g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null), itemp.getHeight(null), color, null);
        else
          g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null), itemp.getHeight(null), color, null);
        g.dispose();
        itemp = image;
      }
      
      File dir = new File(target);
      if (!dir.exists()) {
        dir.mkdirs();
      }
      newFile = new File(target + File.separator + f.getName());
      ImageIO.write((BufferedImage) itemp, "jpg", newFile);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  /**  zooming - By aspect ratio  */
  private static void resize(String src, String target, double ratio, boolean bb) {
    File newFile = null;
    try {
      File f = new File(src);
      BufferedImage bi = ImageIO.read(f);
      // Computing size 
      int width = bi.getWidth();
      int height = bi.getHeight();
      if (Double.valueOf(height)/width<ratio) {
        height = (int)(width*ratio);
      } else {
        width = (int)(Double.valueOf(height)/ratio);
      }
      Image itemp = bi.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH);
      AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(1, 1), null);
      itemp = op.filter(bi, null);
      if (bb) {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();
        g.setColor(color);
        g.fillRect(0, 0, width, height);
        if (width == itemp.getWidth(null))
          g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null), itemp.getHeight(null), color, null);
        else
          g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null), itemp.getHeight(null), color, null);
        g.dispose();
        itemp = image;
      }
      
      File dir = new File(target);
      if (!dir.exists()) {
        dir.mkdirs();
      }
      newFile = new File(target + File.separator + f.getName());
      ImageIO.write((BufferedImage) itemp, "jpg", newFile);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

Img. java:


package util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
 *  The picture  -  The original component 
 * @author xlk
 */
public class Img implements ImgUtil {
  private  String  src;  // Source image or image folder path 
  private  String  target;  // Destination folder path 
  private  boolean  inner;  //true- Include subfolders , false- Current folder only 
  @Override
  public List<File> dispose() {
    return copy();
  }
  /**  copy  -  The initial state of the decorator  */
  private List<File> copy() {
    if (src==null || "".equals(src) || target==null || "".equals(target)) {
      throw new RuntimeException(" The source path or target path cannot be empty ");
    }
    File srcFile = new File(src);
    List<File> list = new ArrayList<File>();
    
    File targetDir = new File(target);
    if (!targetDir.exists()) {
      targetDir.mkdirs();
    }
    a:
    if (srcFile.isDirectory()) {// The source path is the folder 
      File[] subs = srcFile.listFiles();
      if (subs.length<=0) {
        break a;
      }
      for (File sub: subs) {
        if (sub.isDirectory() && inner) {
          list.addAll(new Img(sub.getPath(), target+File.separator+sub.getName(), true).copy());
        } else if (AbstractImgUtil.isImg(sub)) {
          list.add(copy(sub, target));
        }
      }
    } else if (AbstractImgUtil.isImg(srcFile)) {// The source path is the image 
      list.add(copy(srcFile, target));
    }
    return list;
  }
  private File copy(File file, String target) {
    FileInputStream fis = null;
    FileOutputStream fos = null;
    File newFile = null;
    try {
      fis = new FileInputStream(file);
      newFile = new File(target + File.separator + file.getName());
      fos = new FileOutputStream(newFile);
      byte[] bs = new byte[1024*10];
      int len = -1;
      while ((len=fis.read(bs))!=-1) {
        fos.write(bs, 0, len);
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        if (fis!=null) {
          fis.close();
        }
        if (fos!=null) {
          fos.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return newFile;
  }
  public Img() {}
  public Img(String src, String target) {
    this.src = src;
    this.target = target;
  }
  public Img(String src, String target, boolean inner) {
    this.src = src;
    this.target = target;
    this.inner = inner;
  }
  public String getSrc() {
    return src;
  }
  public void setSrc(String src) {
    this.src = src;
  }
  public String getTarget() {
    return target;
  }
  public void setTarget(String target) {
    this.target = target;
  }
  public boolean isInner() {
    return inner;
  }
  public void setInner(boolean inner) {
    this.inner = inner;
  }
}

Click here to download the complete example code.

For more java related content, please refer to the following topics: Java Object-oriented Programming Introduction and Advanced Tutorial, Java Data Structure and Algorithm Tutorial, Java DOM Node Operation Skills Summary, Java File and Directory Operation Skills Summary and Java Cache operation Skills Summary.

I hope this article has been helpful in java programming.


Related articles: