Redis 存储图片 [base64/url/path]vs[object]

Posted jzssuanfa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 存储图片 [base64/url/path]vs[object]相关的知识,希望对你有一定的参考价值。

一、base64图片编解码

  基本流程:从网络获取下载一张图片。然后base64编码,再base64解码,存到本地E盘根文件夹下。
  技术分享
  

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

@SuppressWarnings("restriction")
public class Base64ImageUtils {
    /**
     * 将网络图片进行Base64位编码
     * 
     * @param imageUrl
     *            图片的url路径,如http://.....xx.jpg
     * @return
     */
    public static String encodeImgageToBase64(URL imageUrl) {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
        ByteArrayOutputStream outputStream = null;
        try {
            BufferedImage bufferedImage = ImageIO.read(imageUrl);
            outputStream = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "jpg", outputStream);
        } catch (MalformedURLException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(outputStream.toByteArray());// 返回Base64编码过的字节数组字符串
    }

    /**
     * 将本地图片进行Base64位编码
     * 
     * @param imageFile
     *            图片的url路径,如F:/.....xx.jpg
     * @return
     */
    public static String encodeImgageToBase64(File imageFile) {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
        ByteArrayOutputStream outputStream = null;
        try {
            BufferedImage bufferedImage = ImageIO.read(imageFile);
            outputStream = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "jpg", outputStream);
        } catch (MalformedURLException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(outputStream.toByteArray());// 返回Base64编码过的字节数组字符串
    }

    /**
     * 将Base64位编码的图片进行解码,并保存到指定文件夹
     * 
     * @param base64
     *            base64编码的图片信息
     * @return
     */
    public static void decodeBase64ToImage(String base64, String path,
            String imgName) {
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            FileOutputStream write = new FileOutputStream(new File(path
                    + imgName));
            byte[] decoderBytes = decoder.decodeBuffer(base64);
            write.write(decoderBytes);
            write.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String [] args){
        URL url = null;
        try {
            url = new URL("http://www.faceplusplus.com.cn/wp-content/themes/faceplusplus/assets/img/demo/9.jpg");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        String encoderStr = Base64ImageUtils.encodeImgageToBase64(url);
        System.out.println(encoderStr);

        Base64ImageUtils.decodeBase64ToImage(encoderStr, "E:/", "football.jpg");

    }
}

控制台输出的base64编码后的结果:
技术分享

查看E盘根文件夹:
技术分享

二、Redis对象object存储

  Redis存储对象数据的时候。要进行对象的序列化与反序列化操作。
  

package RedisObject;

import java.io.Serializable;

public class Person implements Serializable {

    private static final long serialVersionUID = 1L;
    private int id;
    private String name;

    public Person() {
    }

    public Person(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package RedisObject;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializeUtil {
    /**
     * 序列化
     * 
     * @param object
     * @return
     */
    public static byte[] serialize(Object object) {
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            byte[] bytes = baos.toByteArray();
            return bytes;
        } catch (Exception e) {

        }
        return null;
    }

    /**
     * 反序列化
     * 
     * @param bytes
     * @return
     */
    public static Object unserialize(byte[] bytes) {
        ByteArrayInputStream bais = null;
        try {
            bais = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bais);
            return ois.readObject();
        } catch (Exception e) {

        }
        return null;
    }
}
package RedisObject;

import redis.clients.jedis.Jedis;

public class PersonRedisTest {
    private static Jedis jedis = null;

    /**
     * 初始化Jedis对象
     * 
     * @throws Exception
     */
    public PersonRedisTest() {
        jedis = new Jedis("127.0.0.1", 6379);
    }

    /**
     * 序列化写对象, 将Person对象写入Redis中
     * 
     */
    public void setObject() {
        jedis.set("person:100".getBytes(),
                SerializeUtil.serialize(new Person(100, "zhangsan")));
        jedis.set("person:101".getBytes(),
                SerializeUtil.serialize(new Person(101, "bruce")));
    }

    /**
     * 反序列化取对象, 用Jedis获取对象
     * 
     */
    public void getObject() {
        byte[] data100 = jedis.get(("person:100").getBytes());
        Person person100 = (Person) SerializeUtil.unserialize(data100);
        System.out.println(String.format("person:100->id=%s,name=%s",
                person100.getId(), person100.getName()));

        byte[] data101 = jedis.get(("person:101").getBytes());
        Person person101 = (Person) SerializeUtil.unserialize(data101);
        System.out.println(String.format("person:101->id=%s,name=%s",
                person101.getId(), person101.getName()));
    }

    public static void main(String[] args) {
        PersonRedisTest rt = new PersonRedisTest();
        rt.setObject();
        rt.getObject();
    }
}

执行main函数结果:
技术分享

查看Redis存储的数据:
技术分享

三、Redis存储图片

  在《Redis入门指南》一书的P22(第22页)中,有这么一段话:
  “字符串类型是Redis中最主要的数据类型,它能存储不论什么形式的字符串,包含二进制数据。你能够用其存储用户的邮箱、JSON化的对象甚至是一张图片。”
  Redis 是一个数据结构类型的server。不是单纯的 key-value 存储。 Redis 里面的键是二进制安全的(二进制安全是指数据在传输过程中保证数据的安全性,包含加密等),因此键的内容不应该包含空格或者换行符。比方 ”hello world” 和 ”hello world\n” 是错误的。
  那么怎么在Redis中存储图片呢?说白了。图片就是一组二进制数据,直接存储二进制数据肯定是不行的,要实现Redis存储二进制数据,那么就得事先实行转化。
  在一、二中已经写了图片base64编解码和redis存储对象的过程。那么我们就能够这样子在Redis中来存储图片:
  

  1. 图片转化成String字符串
    (1)我们能够在Redis存储图片的base64编码或者解码。以KV格式,K为普通字符串,V为图片的base64编码。get(K)后再base64解码就能够了;
    (2)我们也能够在Redis中存储图片的网络url或者本地的path路径,详细实现能够使图片本身存储到磁盘中,然后在Redis中以图片的网络url或者本地的path路径为value(V)值存储。
  2. 图片转化成object对象
    直接在Redis中存储图片对象。使用Java的序列化/反序列化机制进行处理实现。
















以上是关于Redis 存储图片 [base64/url/path]vs[object]的主要内容,如果未能解决你的问题,请参考以下文章

对redis基础知识记录

java实现将图片读取成base64字符串,将base64字符串存储为图片。

JAVA将图片(本地或者网络资源)转为Base64字符串,将base64字符串存储为本地图片

php 将图片转换 base64 格式与还原生成图片

使用 Firebase 存储上传 base64 图像

Redis-内存优化