如何使用 Spring 将 blob 转换为图像

Posted

技术标签:

【中文标题】如何使用 Spring 将 blob 转换为图像【英文标题】:How to convert blob to image with Spring 【发布时间】:2022-01-20 04:36:07 【问题描述】:

我有一个 mysql 数据库,我有一个名为 User 的表,其中包含一个名为 pct 的 Blob 类型的列。

我正在使用 hibernate 执行原生选择查询,如下所示:

   public List<Map<String, Object>> queryExtraction(String sql, QWSInputParam[] qwsInputParams) 

        sql = "SELECT user.name,user.pct FROM user user  WHERE user.id = user.id and user.id in :PARAM0";
        Query query = getSession().createSQLQuery(sql);

        query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
        for (int i = 0; i < qwsInputParams.length; i++) 
            LOGGER.info("PARAM" + i + ": " + Arrays.toString(qwsInputParams[i].getValues()));
            query.setParameterList("PARAM" + i, qwsInputParams[i].getValues());
        

        //LOGGER.info("Query extraction: " + query.toString());
        //query.setTimeout(QUERY_TIME_OUT);
        List<Map<String, Object>> list = query.list();

        Object value = null;

        for (Map<String, Object> map : list) 
            for (Map.Entry<String, Object> entry : map.entrySet()) 
                String key = entry.getKey();
                value = entry.getValue();
                System.out.println("0 " + entry.getValue());

            

        
        return list;
    

我不能使用实体,因为它是一种通用方法,应该适用于任何表,因此与特定表无关。 基本上,当执行查询时,对于 blob 类型的 pct 列,会显示以下值:

[B@1a270232

基于post 我理解这是一个JNI 类型签名。

表中pct值如下图:

是否可以将值 [B@1a270232 转换为 base64 以便我可以在浏览器上显示它? 提前致谢

【问题讨论】:

到目录回答您的“是否可以转换...?”问题:不。JNI​​ 类型签名不包含数据本身。但你真的问错了问题。您要做的不是将 JNI 类型签名转换为图像。您需要实际获取 blob 的内容,而不是 JNI 类型签名。您已经拥有它,形式为byte[]。你做错了什么是你在byte[]上调用toString(),这给了你[B@1a270232。您只需要将 byte[] 转换为 Base64。 @Jesper 您好,感谢您的回复,您能否指导我在字节上调用 toString() 的位置? 我不知道具体在哪里,它不在您发布的代码中。但是[B@1a270232 是您在byte[] 上调用toString() 时得到的。代码末尾的变量list 包含查询结果。在那里你可以在某处找到byte[] 是的,当我调试代码时,你是对的 (entry.getValue()) 它是 byte[] 但是当我显示它时 System.out.println("1 " + entry.getValue()) ;它是 [B@544797e7。但我不确定为什么会这样。我已经更新了代码。谢谢 当您执行System.out.println("1 " + entry.getValue()); 时,您在entry.getValue() 返回的byte[] 上隐式调用toString() 【参考方案1】:

怎么样:

// ... once get hold of a byte array:
  byte[] bytes = (byte[]) entry.getValue();

  System.out.println(Base64Utils.encodeToString(bytes));
// ...

Javadoc:

Spring-Base64Utils

【讨论】:

嗨,我试过了,但出现异常不能为这个(Blob)entry.getValue() 将字节转换为 java.sql.blob 答案已修改。【参考方案2】:

使用 apache IOUtils 的替代解决方案符合您的确切要求。

这是来自我的Github repo。我有Entity 有:

@Lob
private Byte[] userpicture;

The controller 获取要查看的图像:

@GetMapping("appUser/id/appUserimage")
    public void renderImageFromDB(@PathVariable String id, HttpServletResponse response) throws IOException 
        AppUserCommand appUserCommand = appUserService.findCommandById(Long.valueOf(id));

        if (appUserCommand.getUserpicture() != null) 
            byte[] byteArray = new byte[appUserCommand.getUserpicture().length];
            int i = 0;

            for (Byte wrappedByte : appUserCommand.getUserpicture())
                byteArray[i++] = wrappedByte; //auto unboxing
            

            response.setContentType("image/jpeg");
            InputStream is = new ByteArrayInputStream(byteArray);
            IOUtils.copy(is, response.getOutputStream());
        
    

最后是显示图像的view:

<div th:if="$appUser.userpicture == null">
<img th:src="@/images/defaultuser.jpg"   /> 
<a href="#" th:href="@'/appUser/' + $appUser.id + '/image'" role="button">Upload</a> </div>
<div th:if="$appUser.userpicture != null"><img th:src="@'/appUser/' + $appUser.id + '/appUserimage'"   /> 

【讨论】:

以上是关于如何使用 Spring 将 blob 转换为图像的主要内容,如果未能解决你的问题,请参考以下文章

如何将 blob 图像从数据库转换为 html 图像 src

将画布转换为 blob 时如何保持图像大小

如何将 blob 转换为图像并在 React 上显示?

如何将实时图像 url 转换为角度的 blob? [复制]

如何将 blob 图像转换为 base64? base64 变量显示为空

将图像路径转换为 ​​blob react native