Matlab:如何正确使用Java ImageIO类来获取BufferedIMage

发布于 2024-11-06 04:48:58 字数 1835 浏览 3 评论 0原文

我正在尝试在 Matlab 中对数据库中的一些图像数据进行模拟。图像数据来自java,输出为base64编码的字节数组。我不熟悉 [java image] 格式。然而,我根据与我一起工作的人编写的一些java编写了以下Matlab代码。它们遵循相同的基本轮廓,并且 Java 代码能够很好地读取图像。 Matlab 代码如下所示:

function [ result ] = queryDb( theQuery )
  conn   = database( ... ); % connect to the database
  result = fetch( exec( conn, theQuery ) );
  result = result.Data;

  close( conn );
end

data = queryDb( 'sql query to get the data' );
data = uint8( data{1,1} );
data = org.apache.commons.codec.binary.Base64.decodeBase64( data );
data = uint8( 127 + data ); % the base64 decoder returns signed int8

import javax.imageio.ImageIO;
import java.io.ByteArrayInputStream;

dataStream    = ByteArrayInputStream( data );
bufferedimage = ImageIO.read( dataStream );

检查 bufferedimage 后,发现它是一个 double 空数组,而不是 java BufferedImage 实例。

我对 dataStream 进行了一些测试,看看它的行为是否符合预期;类似于以下内容的小型单元测试:

for jj = 1:10
  for kk 1:10
    assert( dataStream.read() == data(kk) );
  end;

  dataStream.reset();
end;

它已检查完毕,因此这使我相信问题出在 ImageIO 或我对它的使用上。

不幸的是,我发现的使用 ImageIO(以及其中一些其他 API)的示例都没有按照我在这里概述的方式使用(即在 Matlab 中)。

此代码使用java .io.ByteArrayInputStream 以相同的方式 - 从某种意义上说,提供的数据是字节数组。

此代码本质上是我的我正在寻找 - 将 java 图像转换为 Matlab 数组。不幸的是,他们通过获取 Matlab 图像,将其转换为 java 图像,然后将其返回来进行作弊。

这段代码使用了ImageIO,但它是这样做的通过从文件流中读取。我尝试将数据写入文件,然后使用 java.io.File 读取它,但无论哪种方式我都得到相同的结果。

所以,我很茫然。

I'm trying to do a mock-up in Matlab on some image data in a database. The image data is from java, output as a base64 encoded byte array. I'm not familiar with the [java image] format. However, I wrote the following Matlab code based on some java written by someone working with me. They follow the same basic outline, and the Java code is able to read the image just fine. The Matlab code looks like this:

function [ result ] = queryDb( theQuery )
  conn   = database( ... ); % connect to the database
  result = fetch( exec( conn, theQuery ) );
  result = result.Data;

  close( conn );
end

data = queryDb( 'sql query to get the data' );
data = uint8( data{1,1} );
data = org.apache.commons.codec.binary.Base64.decodeBase64( data );
data = uint8( 127 + data ); % the base64 decoder returns signed int8

import javax.imageio.ImageIO;
import java.io.ByteArrayInputStream;

dataStream    = ByteArrayInputStream( data );
bufferedimage = ImageIO.read( dataStream );

Upon inspection of bufferedimage, it is an empty array of double as opposed to a java BufferedImage instance.

I ran a few tests on dataStream to see if it behaved as expected; sort of a mini unit test along the lines of:

for jj = 1:10
  for kk 1:10
    assert( dataStream.read() == data(kk) );
  end;

  dataStream.reset();
end;

It checked out, so this leads me to believe the problem is with ImageIO or my use of it.

Unfortunately, none of the examples I've found for using ImageIO (and some of these other APIs) are used in quite the manner I outline here (in Matlab that is).

This code uses java.io.ByteArrayInputStream in the same manner -- in the sense that the provided data is an array of bytes.

This code is essentially what I'm looking to do -- convert a java image to a Matlab array. Unfortunately, they cheat by taking a Matlab image, turning it into a java image, then turn it back.

This code uses ImageIO, but it does so by reading from a file stream. I tried writing the data out to a file then reading it in using java.io.File, but I get the same result either way.

So, I'm at a loss.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅笑轻吟梦一曲 2024-11-13 04:48:58

问题中概述的方法有效...我与上面的代码有任何不同之处是我没有将 127 添加到 uint8 数组中:

% Do all the imports
% sql query to get the data
dataStream    = ByteArrayInputStream( decodeBase64( rows.data{1} ) );
bufferedImage = ImageIO.read( dataStream );
[w h] = deal( theWidth, theHeight );
imageData     = uint8( bufferedImage.getData.getPixels( 0,0,w,h,[] ) );
imageData     = permute( reshape( imageData, [3 w h] ), [2 3 1] );

imshow( imageData );
% voila

编辑 合并文本 @kchja < a href="http://www.mathworks.com/support/solutions/en/data/1-2WPAYR/?solution=1-2WPAYR" rel="nofollow">链接到,以防该链接变得无效:

主题:如何将“Java Image”对象转换为 MATLAB 图像
矩阵?

问题描述:IM2JAVA函数可用于转换
将 MATLAB 图像转换为 Java 图像。我想转换 Java 图像
到 MATLAB 图像。

解决方案:没有内置函数可以将Java图像转换为
MATLAB 图像。但是,使用 Java API 您可以提取数据
从Java图像并将其存储为矩阵,这是MATLAB的图像
代表。

下面是将 MATLAB 图像转换为 Java 并返回为
MATLAB 图像。本例中使用的图像是 MATLAB 的一部分
演示并且位于 MATLAB 路径上。在此示例中,“getPixels”
Java 类“Raster”的函数返回 RGB 值
图像。

根据 Java 映像的格式,可能需要进行额外的工作
必需的。 Java 图像可以以多种格式之一存储;这
“getPixels”函数返回该格式的像素数据。了解更多
信息,请参阅 java.awt.image.Raster 类的 javadoc 页面
http://java.sun。 com/j2se/1.5.0/docs/api/java/awt/image/Raster.html

% create java image
I = imread('office_3.jpg');
javaImage = im2java(I);

% get image properties
H=javaImage.getHeight;
W=javaImage.getWidth;

% repackage as a 3D array (MATLAB image format)
B = uint8(zeros([H,W,3]));
pixelsData = uint8(javaImage.getBufferedImage.getData.getPixels(0,0,W,H,[]));
for i = 1 : H
base = (i-1)*W*3+1;
B(i,1:W,:) = deal(reshape(pixelsData(base:(base+3*W-1)),3,W)');
end

% display image
imshow(B);

以下是实现此目的的另外两种方法(以更
优化方式):

示例 1:(执行速度更快)

pixelsData = reshape(typecast(jImage.getData.getDataStorage, 'uint8'), 4, w, h);
imgData = cat(3, ...
        transpose(reshape(pixelsData(3, :, :), w, h)), ...
        transpose(reshape(pixelsData(2, :, :), w, h)), ...
        transpose(reshape(pixelsData(1, :, :), w, h)));

示例2:

imgData = zeros([H,W,3],'uint8');
pixelsData = reshape(typecast(javaImage.getBufferedImage.getData.getDataStorage,'uint32'),W,H).';
imgData(:,:,3) = bitshift(bitand(pixelsData,256^1-1),-8*0);
imgData(:,:,2) = bitshift(bitand(pixelsData,256^2-1),-8*1);
imgData(:,:,1) = bitshift(bitand(pixelsData,256^3-1),-8*2);

The approach outlined in the question works ... the only thing I have that differs in any way from the code above is I'm not adding 127 to the uint8 array:

% Do all the imports
% sql query to get the data
dataStream    = ByteArrayInputStream( decodeBase64( rows.data{1} ) );
bufferedImage = ImageIO.read( dataStream );
[w h] = deal( theWidth, theHeight );
imageData     = uint8( bufferedImage.getData.getPixels( 0,0,w,h,[] ) );
imageData     = permute( reshape( imageData, [3 w h] ), [2 3 1] );

imshow( imageData );
% voila

edit Incorporating the text @kchja linked to, in case that link becomes invalid:

Subject: How can I convert a "Java Image" object into a MATLAB image
matrix?

Problem Description: The IM2JAVA function is available for converting
a MATLAB image into a Java image. I would like to convert a Java image
to a MATLAB image.

Solution: There is no built-in function to convert Java images into
MATLAB images. However using the Java API you can extract the data
from a Java image and store it as a matrix, which is MATLAB's image
representation.

Below is an example of converting a MATLAB image to Java and back to a
MATLAB image. The image used in this example is part of the MATLAB
demos and is on the MATLAB path. In this example, the "getPixels"
function of the Java class "Raster" returns the RGB values for the
image.

Depending upon the format of your Java image, additional work may be
required. Java images can be stored in one of many formats; the
"getPixels" function returns the pixel data in that format. For more
information, see the javadoc page for the java.awt.image.Raster class
at http://java.sun.com/j2se/1.5.0/docs/api/java/awt/image/Raster.html

% create java image
I = imread('office_3.jpg');
javaImage = im2java(I);

% get image properties
H=javaImage.getHeight;
W=javaImage.getWidth;

% repackage as a 3D array (MATLAB image format)
B = uint8(zeros([H,W,3]));
pixelsData = uint8(javaImage.getBufferedImage.getData.getPixels(0,0,W,H,[]));
for i = 1 : H
base = (i-1)*W*3+1;
B(i,1:W,:) = deal(reshape(pixelsData(base:(base+3*W-1)),3,W)');
end

% display image
imshow(B);

The following are two other ways to implement this (in a more
optimized manner):

Example 1: (Faster execution)

pixelsData = reshape(typecast(jImage.getData.getDataStorage, 'uint8'), 4, w, h);
imgData = cat(3, ...
        transpose(reshape(pixelsData(3, :, :), w, h)), ...
        transpose(reshape(pixelsData(2, :, :), w, h)), ...
        transpose(reshape(pixelsData(1, :, :), w, h)));

Example 2:

imgData = zeros([H,W,3],'uint8');
pixelsData = reshape(typecast(javaImage.getBufferedImage.getData.getDataStorage,'uint32'),W,H).';
imgData(:,:,3) = bitshift(bitand(pixelsData,256^1-1),-8*0);
imgData(:,:,2) = bitshift(bitand(pixelsData,256^2-1),-8*1);
imgData(:,:,1) = bitshift(bitand(pixelsData,256^3-1),-8*2);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文