读取文件生成固定大小的水印图片

[quote]package com.lovesz.mf.util;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.Date;

import javax.imageio.ImageIO;

import org.apache.log4j.Logger;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
*
* @author
*
*/
public class ImageTool
{
public static Logger logger = Logger.getLogger(ImageTool.class);

/**
* @param file
* 需要读取的文件
* @param targetImgPath
* 要写的目标地址图片文件路径(包括图片名称 比如:83193_7484.jpg 的83193_7484部分)
* @param picFormat
* 图片格式
* @param imgWidth
* 目标图片的宽度
* @param imgHeight
* 目标图片的高度
* @return false 执行失败 true 执行成功
*/
public static boolean generateImage(File file, String targetImgPath, String picFormat, int imgWidth, int imgHeight)
throws IOException
{

logger.info("----------调用生成图片方法,产生图片开始----------");

// 读取文件,可能产生IO异常
BufferedImage sourceImg = ImageIO.read(file);
logger.info("图片宽度" + sourceImg.getWidth());
logger.info("图片高度" + sourceImg.getHeight());
logger.info("图片类型" + sourceImg.getType());

// 首先判断长宽

// 如果是长 > 宽 flag 为true 否则为FALSE
boolean flag = true;

int img_w = sourceImg.getWidth();
int img_h = sourceImg.getHeight();
// 如果长度大于等于高度则 flag = true;
if (img_w >= img_h)
{
flag = true;
logger.info("图片长度Width大于或者等于高度Height");
}
else
{
flag = false;
logger.info("图片长度Width小于高度Height");
}

File itemFile = new File("");
Float f = new Float(0);
// 长大于宽的情况下
if (flag)
{
f = ((new Float(img_h) * imgWidth) / new Float(img_w));
logger.info("新生成的图片的高度height是:" + f);

int newHeight = f.intValue() + 1;



BufferedImage image = new BufferedImage(imgWidth, newHeight, BufferedImage.TYPE_INT_RGB); // 表示一个图像,该图像具有打包成整数像素的 8 位

Graphics g = image.createGraphics();

g.drawImage(sourceImg, 0, 0, imgWidth, newHeight, null);
// 释放此图形的上下文并释放它所使用的所有系统资源。
g.dispose();

// 拼接图片路径
String targetFileName = targetImgPath + picFormat;
itemFile = new File(targetFileName);
FileOutputStream out_pre = new FileOutputStream(itemFile);
JPEGImageEncoder encoder_pre = JPEGCodec.createJPEGEncoder(out_pre);
encoder_pre.encode(image);
out_pre.flush();
out_pre.close();
}
else
{
f = ((new Float(img_w) * imgHeight) / new Float(img_h));
logger.info("新生成的图片的宽度width是:" + f);

int newWidth = f.intValue() + 1;


BufferedImage image = new BufferedImage(newWidth, imgHeight, BufferedImage.TYPE_INT_RGB); // 表示一个图像,该图像具有打包成整数像素的 8 位

Graphics g = image.createGraphics();

g.drawImage(sourceImg, 0, 0, newWidth, imgHeight, null);
// 释放此图形的上下文并释放它所使用的所有系统资源。
g.dispose();

// 写新文件的地址
// 拼接图片路径
String targetFileName = targetImgPath + picFormat;
itemFile = new File(targetFileName);
FileOutputStream out_pre = new FileOutputStream(itemFile);
JPEGImageEncoder encoder_pre = JPEGCodec.createJPEGEncoder(out_pre);
encoder_pre.encode(image);
out_pre.flush();
out_pre.close();
}
//s生成图片路径 itemFile
/**
* 下面代码的"D:\\1.jpg",是我把商品图片(需要被加水印的图片)
* 保存在D盘,并起名为1.jpg,这里您根据您的图片的实际位置来输
* 入正确的文件路径。
*/
File formerFile = new File("c:/1.jpg");
Image formerImage = ImageIO.read(formerFile); //itemFile 就是要被水印的文件
//以下2行代码分别获得图片的宽(width)和高(height)
int width = formerImage.getWidth(null); //640px
int height = formerImage.getHeight(null); //480px
System.out.println("原始图片的宽为:" + width + "\n原始图片的高为:" + height);

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.createGraphics();
g.drawImage(formerImage, 0, 0, width, height, null);

//File waterMarkFile = itemFile;
Image waterMarkImage = ImageIO.read(itemFile);
int widthWMI = waterMarkImage.getWidth(null);
int heightWMI = waterMarkImage.getHeight(null);
/**
* 以下2行代码的x,y分别表示水印图片在原始图片的位置。
* x,y为坐标。width,height为商品图片的宽和高。
* width * 0.5 表示水印图片的水平位置覆盖在商品图片
* 水平位置的正中间。height * 0.5 表示垂直位置。
* 最终无论商品图片的宽高是多少,水印图片都会显示在
* 商品图片的正中间。
* 您可以根据您的需求,更改0.5这个数值,达到您想要的效果。
* 这里我说的商品图片就是要被水印覆盖的图片。
*/
int x = (int) (640 - widthWMI) / 2; //"0.5"小数越大,水印越向左移动。
int y = (int) (480 - heightWMI) / 2; //"0.5"小数越大,水印越向上移动。
g.drawImage(waterMarkImage, width - widthWMI - x, height - heightWMI - y, widthWMI, heightWMI, null);

/**
* 输出被加上水印的图片,也就是最终的效果。
* 注意!下面代码的"D:\\1.jpg"是最后输出
* 的文件,如果跟你原始文件的路径和名字相同
* 的话,那么会覆盖掉原始文件。
* 如:我的原始文件位于"D:\\1.jpg",而下
* 面的代码运行之后,我的原始文件就会丢失被
* 覆盖掉。
* 您可以根据您的需要把加上水印后的图片放到
* 您指定的文件路径。
*/
g.dispose();
FileOutputStream out = new FileOutputStream("c:\\2222.jpg");
//下面代码将被加上水印的图片转换为JPEG、JPG文件
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(image);
out.close();
System.out.println("水印已经添加成功!");

logger.info("----------调用生成图片方法,产生图片结束----------");
return true;
}

// 第2种方法:使用NIO中的管道到管道传输
// 实现方法很简单,分别对2个文件构建输入输出流,并且使用一个字节数组作为我们内存的缓存器, 然后使用流从f1
// 中读出数据到缓存里,在将缓存数据写到f2里面去.这里的缓存是2MB的字节数组
// 现方法:在第一种实现方法基础上对输入输出流获得其管道,然后分批次的从f1的管道中像f2的管道中输入数据每次输入的数据最大为2MB
// 由于另外2种方法内部都使用了
// 字节数组作为缓存中转,在加上NIO内部有一个贴近系统的缓存区,这无意就增加了另一个缓存器,所以相对于这2个方法就要慢许多,,如果不使用
// 字节数组作为数据中转的话相信速度会更快的..
// 不过比较惊讶的是 管道向管道传输的速度还是真挺吓人,,,
public static long forFileCopy(File inputFile, File destFile) throws Exception
{
long time = new Date().getTime();
int length = 2097152;
FileInputStream in = new FileInputStream(inputFile);
FileOutputStream out = new FileOutputStream(destFile);
FileChannel inC = in.getChannel();
FileChannel outC = out.getChannel();
int i = 0;
while (true)
{
if (inC.position() == inC.size())
{
inC.close();
outC.close();
return new Date().getTime() - time;
}
if ((inC.size() - inC.position()) < 20971520)
length = (int) (inC.size() - inC.position());
else
length = 20971520;
inC.transferTo(inC.position(), length, outC);
inC.position(inC.position() + length);
i++;
}
}

public static void main(String[] args) throws Exception
{
File file = new File("c:/55.jpg");
generateImage(file, "c:/33.jpg", ".jpg", 640, 480);
}
}
[/quote]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值