【问题标题】:how to store an image to redis using java / spring如何使用java / spring将图像存储到redis
【发布时间】:2013-07-28 18:56:02
【问题描述】:

我在我的图片上传服务器上使用 redis 和 spring 框架。我需要将图像存储到redis。我发现了以下问题,但它是针对 python 的。
how to store an image into redis using python / PIL

我不确定这是否是最好的方法,但我想知道如何在 java 中做到这一点(最好使用 spring 框架)。我正在使用使用 jedis 的 spring-data-redis。

我想知道将图像存储在redis中是否是一个好策略。

【问题讨论】:

    标签: java spring redis jedis


    【解决方案1】:

    Redis 是二进制安全的,因此对于 Jedis,您可以使用 BinaryJedis 来存储二进制数据,就像存储在 Redis 中的任何其他类型的值一样。

    不,我不认为将图像存储在 Redis 中并因此存储在内存中是一个好策略。那一定是一个非常特殊的用例。

    【讨论】:

    • 嗨!云是否更适合存储图像?
    【解决方案2】:

    首先,Redis 不是存储图像的好选择。 Redis 是内存中的,因此将图像等文件放入内存不是一个好的步骤。

    如果要输入图片,可以如下使用

    以下是步骤

    1) 使用以下 jars 制作您的 maven pom.xml

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
    
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
    
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>
    
        <dependency>
               <groupId>org.springframework.data</groupId>
               <artifactId>spring-data-redis</artifactId>
               <version>1.3.0.RELEASE</version>
            </dependency>
    
                <dependency>
                   <groupId>redis.clients</groupId>
                   <artifactId>jedis</artifactId>
                   <version>2.4.1</version>
                </dependency>
    
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.0</version>
        </dependency>
    

    2) 使您的配置 xml 如下

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p"
            xmlns:c="http://www.springframework.org/schema/c"
            xmlns:cache="http://www.springframework.org/schema/cache"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans     
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context-3.0.xsd
    
            http://www.springframework.org/schema/cache 
            http://www.springframework.org/schema/cache/spring-cache.xsd">
    
    
    
        <bean id="jeidsConnectionFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
          p:host-name="localhost" p:port="6379" p:password="" />
    
         <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
          p:connection-factory-ref="jeidsConnectionFactory" />
    
         <bean id="imageRepository" class="com.self.common.api.poc.ImageRepository">
          <property name="redisTemplate" ref="redisTemplate"/>
         </bean>
    
    </beans>
    

    3) 让你的类如下

    package com.self.common.api.poc;
    
    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.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    public class RedisMainApp {
    
     public static void main(String[] args) throws IOException {
      ApplicationContext applicationContext = new ClassPathXmlApplicationContext("mvc-dispatcher-servlet.xml");
      ImageRepository imageRepository = (ImageRepository) applicationContext.getBean("imageRepository");
    
      BufferedImage img = ImageIO.read(new File("files/img/TestImage.png"));
      BufferedImage newImg;
      String imagestr;
      imagestr = encodeToString(img, "png");
      Image image1 = new Image("1", imagestr);
    
      img = ImageIO.read(new File("files/img/TestImage2.png"));
      imagestr = encodeToString(img, "png");
      Image image2 = new Image("2", imagestr);
    
      imageRepository.put(image1);
      System.out.println(" Step 1 output : " + imageRepository.getObjects());
      imageRepository.put(image2);
      System.out.println(" Step 2 output : " + imageRepository.getObjects());
      imageRepository.delete(image1);
      System.out.println(" Step 3 output : " + imageRepository.getObjects());
    
     }
    
     /**
      * Decode string to image
      * @param imageString The string to decode
      * @return decoded image
      */
     public static BufferedImage decodeToImage(String imageString) {
    
         BufferedImage image = null;
         byte[] imageByte;
         try {
             BASE64Decoder decoder = new BASE64Decoder();
             imageByte = decoder.decodeBuffer(imageString);
             ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
             image = ImageIO.read(bis);
             bis.close();
         } catch (Exception e) {
             e.printStackTrace();
         }
         return image;
     }
    
     /**
      * Encode image to string
      * @param image The image to encode
      * @param type jpeg, bmp, ...
      * @return encoded string
      */
     public static String encodeToString(BufferedImage image, String type) {
         String imageString = null;
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
    
         try {
             ImageIO.write(image, type, bos);
             byte[] imageBytes = bos.toByteArray();
    
             BASE64Encoder encoder = new BASE64Encoder();
             imageString = encoder.encode(imageBytes);
    
             bos.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
         return imageString;
     }
    }
    
    package com.self.common.api.poc;
    
    public class Image implements DomainObject {
    
     public static final String OBJECT_KEY = "IMAGE";
    
     public Image() {
     }
    
     public Image(String imageId, String imageAsStringBase64){
      this.imageId = imageId;
      this.imageAsStringBase64 = imageAsStringBase64;
     }
     private String imageId;
     private String imageAsStringBase64;
    
     public String getImageId() {
      return imageId;
     }
    
     public void setImageId(String imageId) {
      this.imageId = imageId;
     }
    
     public String getImageName() {
      return imageAsStringBase64;
     }
    
     public void setImageName(String imageAsStringBase64) {
      this.imageAsStringBase64 = imageAsStringBase64;
     }
    
     @Override
     public String toString() {
      return "User [id=" + imageAsStringBase64 + ", imageAsBase64String=" + imageAsStringBase64 + "]";
     }
    
     @Override
     public String getKey() {
      return getImageId();
     }
    
     @Override
     public String getObjectKey() {
      return OBJECT_KEY;
     }
    }
    
    package com.self.common.api.poc;
    
    import java.io.Serializable;
    
    public interface DomainObject extends Serializable {
    
     String getKey();
    
     String getObjectKey();
    }
    
    package com.self.common.api.poc;
    
    import java.util.List;
    
    import com.self.common.api.poc.DomainObject;
    
    public interface Repository<V extends DomainObject> {
    
     void put(V obj);
    
     V get(V key);
    
     void delete(V key);
    
     List<V> getObjects();
    }
    
    package com.self.common.api.poc;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    
    import com.self.common.api.poc.DomainObject;
    
    public class ImageRepository implements Repository<Image>{
    
     @Autowired
     private RedisTemplate<String,Image> redisTemplate;
    
     public RedisTemplate<String,Image> getRedisTemplate() {
      return redisTemplate;
     }
    
     public void setRedisTemplate(RedisTemplate<String,Image> redisTemplate) {
      this.redisTemplate = redisTemplate;
     }
    
     @Override
     public void put(Image image) {
      redisTemplate.opsForHash()
        .put(image.getObjectKey(), image.getKey(), image);
     }
    
     @Override
     public void delete(Image key) {
      redisTemplate.opsForHash().delete(key.getObjectKey(), key.getKey());
     }
    
     @Override
     public Image get(Image key) {
      return (Image) redisTemplate.opsForHash().get(key.getObjectKey(),
        key.getKey());
     }
    
     @Override
     public List<Image> getObjects() {
      List<Image> users = new ArrayList<Image>();
      for (Object user : redisTemplate.opsForHash().values(Image.OBJECT_KEY) ){
       users.add((Image) user);
      }
      return users;
     }
    
    }
    

    有关 srinf jedis 的更多参考,您可以查看http://www.javacodegeeks.com/2012/06/using-redis-with-spring.html

    示例代码取自http://javakart.blogspot.in/2012/12/spring-data-redis-hello-world-example.html

    【讨论】:

    • 嗨!我应该改用云并通过 url 获取我的图像吗?
    【解决方案3】:

    将图像转换为base64字符串并作为键值对存储在redis中。 如何将图像转换为 base64 字符串可以在这里找到 http://ben-bai.blogspot.in/2012/08/java-convert-image-to-base64-string-and.html

    【讨论】:

      【解决方案4】:

      从@global-warrior 的回答中得到提示,这就是我所做的(需要 Java 8):

      private String getEncodedString(byte[] bytes) {
          return new String(Base64.getEncoder().encode(bytes));
      }
      
      private byte[] getDecodedByteArray(String string) {
          return Base64.getDecoder().decode(string.getBytes());
      }
      

      并使用spring data redis存储库和实体进行存储和检索:

      @RedisHash("image") @Data @AllArgsConstructor
      public class RedisImageEntity {
          @Id String checksum;
          String image;
      }
      
      public interface RedisImageRepository extends CrudRepository<RedisImageEntity, String> {}
      

      最后,在控制器中:

      @RequestMapping(value = "/upload", method = RequestMethod.POST)
      ResponseEntity<ImageUploadDTO> uploadImage(MultipartFile image) {
          // ...
          redisImageRepository.save(
              new RedisImageEntity(checksum, getEncodedString(image.getBytes))
          );
          // ...
      }
      
      @RequestMapping(value = "/image", method = RequestMethod.GET)
      ResponseEntity<ImageResponseDTO> getImage(String checksum) {
          // ...
          prepareImage(getDecodedByteArray(
              redisImageRepository.findById(checksum).orElse(null)
          ));
          // ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-24
        • 1970-01-01
        • 1970-01-01
        • 2017-06-12
        • 1970-01-01
        • 2018-12-16
        • 2017-03-26
        • 2019-02-07
        相关资源
        最近更新 更多