Note:
图片转二进制数据只需转化为bate数组二进制数据即可,例如要求httpclient发送图片二进制数据即是把生成的bate数组数据发送过去。如果对方明确提出是字符串格式编码,再进一步转化就好了
使用Base64转换图片
利用Base64实现二进制和图片之间的转换,具体代码如下:
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.tomcat.util.codec.binary.Base64;
public class ImageBinary {
public static void main(String[] args) {
String fileName = "D://code//test.jpg";
System.out.println(getImageBinary(fileName));
saveImage(getImageBinary(fileName));
}
/*
* 图片转换为二进制
*
* @param fileName
* 本地图片路径
* @return
* 图片二进制流
* */
public static String getImageBinary(String fileName) {
File f = new File(fileName);
BufferedImage bi;
try {
bi = ImageIO.read(f);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bi, "jpg", baos);
byte[] bytes = baos.toByteArray();
return Base64.encodeBase64String(bytes);
//return encoder.encodeBuffer(bytes).trim();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 将二进制转换为图片
*
* @param base64String
* 图片二进制流
*
*/
public static void saveImage(String base64String) {
try {
byte[] bytes1 = Base64.decodeBase64(base64String);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
BufferedImage bi1 = ImageIO.read(bais);
File w2 = new File("D://code//22.jpg");// 可以是jpg,png,gif格式
ImageIO.write(bi1, "jpg", w2);// 不管输出什么格式图片,此处不需改动
} catch (IOException e) {
e.printStackTrace();
}
}
}
网络地址url与本地图片获取图片字节流
若通过url访问图片并转换为二进制流,就不能按照上述方法。通过url获取图片涉及url、网络状态等各种情况。在代码中涉及两种不同的方法:一个是通过url的形式,另一个是直接访问本地资源(即图片路径)。详见以下代码:
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class ImageUtil {
/**
* 根据地址获得数据的字节流
*
* @param strUrl
* 网络连接地址
* @return
*/
public static byte[] getImageFromNetByUrl(String strUrl) {
try {
URL url = new URL(strUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5 * 1000);
InputStream inStream = conn.getInputStream();// 通过输入流获取图片数据
byte[] btImg = readInputStream(inStream);// 得到图片的二进制数据
return btImg;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 根据地址获得数据的字节流
*
* @param strUrl
* 本地连接地址
* @return
*/
public byte[] getImageFromLocalByUrl(String strUrl) {
try {
File imageFile = new File(strUrl);
InputStream inStream = new FileInputStream(imageFile);
byte[] btImg = readInputStream(inStream);// 得到图片的二进制数据
return btImg;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 从输入流中获取数据
*
* @param inStream
* 输入流
* @return
* @throws IOException
* @throws Exception
*/
private static byte[] readInputStream(InputStream inStream) throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[10240];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
inStream.close();
return outStream.toByteArray();
}
public static void main(String[] args) {
System.out.println(b);
}
}
url获取图片字节流
本节介绍的方法可以说是前两种方法的结合体,但是在两者的基础上有所优化,如对url的状态做判断,此方法仅供参考,可根据具体需求做相应调整。
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import javax.imageio.ImageIO;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
public class ImageUtils {
/*
* 获取原图片二进制流
*
* @param imageUrl
* 原图片地址
* */
public static String getImageBinary(String imageUrl) {
String data = null;
try {
int HttpResult = 0; // 服务器返回的状态
URL url = new URL(imageUrl); // 创建URL
URLConnection urlconn = url.openConnection(); // 试图连接并取得返回状态码
urlconn.connect();
HttpURLConnection httpconn = (HttpURLConnection) urlconn;
HttpResult = httpconn.getResponseCode();
if (HttpResult != HttpURLConnection.HTTP_OK) // 不等于HTTP_OK则连接不成功
System.out.print("failed");
else {
BufferedInputStream bis = new BufferedInputStream(urlconn.getInputStream());
BufferedImage bm = ImageIO.read(bis);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String type = imageUrl.substring(imageUrl.length() - 3);
ImageIO.write(bm, type, bos);
bos.flush();
data = Base64.encode(bos.toByteArray());
bos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
public static void main(String[] args) {
System.out.println(result);
}
}
url获取图片字节流
本方法实现了主要实现了以下几个功能:
1、通过url将图片转换为字节流(十六进制的形式),并实现字节流与图片之间的相互转换;
2、将本地图片转换为字节流(十六进制的形式),并实现字节流与图片之间的相互转换;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import javax.imageio.ImageIO;
public class Utils {
/**
* 图片转换成二进制字符串
*
* @param imageUrl
* 图片url
* @return String 二进制流
*/
public static String getImgeHexStringByUrl(String imageUrl) {
String res = null;
try {
int HttpResult = 0; // 服务器返回的状态
URL url = new URL(imageUrl); // 创建URL
URLConnection urlconn = url.openConnection(); // 试图连接并取得返回状态码
urlconn.connect();
HttpURLConnection httpconn = (HttpURLConnection) urlconn;
HttpResult = httpconn.getResponseCode();
if (HttpResult != HttpURLConnection.HTTP_OK) // 不等于HTTP_OK则连接不成功
System.out.print("failed");
else {
BufferedInputStream bis = new BufferedInputStream(urlconn.getInputStream());
BufferedImage bm = ImageIO.read(bis);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String type = imageUrl.substring(imageUrl.length() - 3);
ImageIO.write(bm, type, bos);
bos.flush();
byte[] data = bos.toByteArray();
res = byte2hex(data);
bos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
/**
* 本地图片转换成二进制字符串
*
* @param imageUrl
* 图片url
* @return String 二进制流
*/
public static String getImgeHexStringByLocalUrl(String imageUrl) {
String res = null;
try {
File imageFile = new File(imageUrl);
InputStream inStream = new FileInputStream(imageFile);
BufferedInputStream bis = new BufferedInputStream(inStream);
BufferedImage bm = ImageIO.read(bis);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String type = imageUrl.substring(imageUrl.length() - 3);
ImageIO.write(bm, type, bos);
bos.flush();
byte[] data = bos.toByteArray();
res = byte2hex(data);
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
/**
* @title 根据二进制字符串生成图片
* @param data
* 生成图片的二进制字符串
* @param fileName
* 图片名称(完整路径)
* @param type
* 图片类型
* @return
*/
public static void saveImage(String data, String fileName, String type) {
BufferedImage image = new BufferedImage(300, 300, BufferedImage.TYPE_BYTE_BINARY);
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
try {
ImageIO.write(image, type, byteOutputStream);
// byte[] date = byteOutputStream.toByteArray();
byte[] bytes = hex2byte(data);
RandomAccessFile file = new RandomAccessFile(fileName, "rw");
file.write(bytes);
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 反格式化byte
*
* @param s
* @return
*/
public static byte[] hex2byte(String s) {
byte[] src = s.toLowerCase().getBytes();
byte[] ret = new byte[src.length / 2];
for (int i = 0; i < src.length; i += 2) {
byte hi = src[i];
byte low = src[i + 1];
hi = (byte) ((hi >= 'a' && hi <= 'f') ? 0x0a + (hi - 'a') : hi - '0');
low = (byte) ((low >= 'a' && low <= 'f') ? 0x0a + (low - 'a') : low - '0');
ret[i / 2] = (byte) (hi << 4 | low);
}
return ret;
}
/**
* 格式化byte
*
* @param b
* @return
*/
public static String byte2hex(byte[] b) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
char[] out = new char[b.length * 2];
for (int i = 0; i < b.length; i++) {
byte c = b[i];
out[i * 2] = Digit[(c >>> 4) & 0X0F];
out[i * 2 + 1] = Digit[c & 0X0F];
}
return new String(out);
}
public static void main(String[] args) {
String fileName = "D://code//cc.png";
* url形式
* */
String result = getImgeHexStringByUrl(url);
System.out.println(result);
saveImage(result,fileName,"png");
/*
* 本地图片形式
* */
String result1 = getImgeHexStringByLocalUrl(fileName);
System.out.println(result1);
saveImage(result1,outImage,"png");
}
}
通过url下载图片
在给定url的情况下,可将url所访问的图片下载至本地。具体代码如下:
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
public class downimageUtil {
private static final String filePath = "C://Users//lizhihui//Desktop//";
/*
* 根据url下载图片
*
* @param destUrl
* url连接
* @return
* 图片保存路径
* */
public String saveToFile(String destUrl) {
String fileName = "";
FileOutputStream fos = null;
BufferedInputStream bis = null;
HttpURLConnection httpUrl = null;
URL url = null;
int BUFFER_SIZE = 1024;
byte[] buf = new byte[BUFFER_SIZE];
int size = 0;
try {
url = new URL(destUrl);
httpUrl = (HttpURLConnection) url.openConnection();
httpUrl.connect();
bis = new BufferedInputStream(httpUrl.getInputStream());
for (String string : destUrl.split("/")) {
if (string.contains("png") || string.contains("png") || string.contains("gif")) {
fileName = string;
}
}
fos = new FileOutputStream(filePath + fileName);
while ((size = bis.read(buf)) != -1) {
fos.write(buf, 0, size);
}
fos.flush();
} catch (IOException e) {
} catch (ClassCastException e) {
} finally {
try {
fos.close();
bis.close();
httpUrl.disconnect();
} catch (IOException e) {
} catch (NullPointerException e) {
}
}
return filePath + fileName;
}
public static void main(String[] args) {
downimageUtil dw = new downimageUtil();
}
}
根据图片网络地址获取二进制与二进制转图片亲测实例:
/**
* 根据图片地址获得数据的字节流
*
* @param strUrl
* @return
*/
public static byte[] getImageFromNetByUrl(String strUrl) {
try {
URL url = new URL(strUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5 * 1000);
InputStream inStream = conn.getInputStream();// 通过输入流获取图片数据
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
byte[] btImg = outStream.toByteArray();// 得到图片的二进制数据
inStream.close();
outStream.close();
conn.disconnect();
return btImg;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//byte数组到图片
public static void byte2image(byte[] data,String path){
if(data.length<3||path.equals("")) return;
try{
FileImageOutputStream imageOutput = new FileImageOutputStream(new File(path));
imageOutput.write(data, 0, data.length);
imageOutput.close();
System.out.println("Make Picture success,Please find image in " + path);
} catch(Exception ex) {
System.out.println("Exception: " + ex);
ex.printStackTrace();
}
}
到此,对于图片的处理结束,这是在写图片压缩服务器时所用到的部分技术,当然在此基本上有所改进,在此不再一一列举,对于图片的压缩方法后续也会整理出来,欢迎查看!虽然写出来了,但还没进行压力测试,优化等一系列后续工作。就先这样吧......