Java中高字节和低字节_关于java:从图像字节数组中提取高字节和低字节

我在字节级别上进行图像压缩相对较新,并且当前正在使用Java图像预处理器,该图像将获取bmp图像,将其转换为8位无符号灰度,然后根据之前的高低将其字节堆叠导出并压缩它。经过大量研究和测试了各种字节提取方法之后,我仍然看不到所需的结果。在继续之前,应该注意的是,所有这些图像最初都是DICOM格式的,我正在使用ij.plugin.DICOM包将像素数据提取为bmp图像。

下面的描述用以下代码表示。目前,我正在读取原始图像作为缓冲图像,将其转换为灰度,然后从Raster获取图像字节。然后,我获取这些字节,并使用在stackoverflow上找到的其他代码,并将其"转换"为二进制位的字符串表示形式。然后,我将该字符串发送到字符数组。下一步可能是无关紧要的,但是我想在删除它之前获取您的输入(因为我是新来的)。我创建一个Bitset并遍历"二进制"字符数组。如果字符值为" 1",则将BitSet中的该位置设置为true。然后,我将BitSet发送到另一个字节数组。

然后创建两个新的字节数组,一个用于高字节,另一个用于低字节。使用for循环,我遍历"位"数组并将每4个"位"存储在高字节或低字节中,具体取决于我们在数组中的位置。

最后,我获取DICOM标签数据,从中创建一个字节数组,然后将标签数组,高字节数组和低字节数组堆叠在一起。我的预期结果是将图像矩阵"拆分",其上半部分包含所有高字节,下半部分包含所有低字节。有人告诉我标记字节会很小,它们不应该影响最终结果(我已经在没有它们的情况下测试了图像,只是为了确保没有明显的差异)。

下面是代码。如果您有任何疑问,请告诉我,我将相应地修改我的帖子。我试图包括所有相关数据。让我知道您是否需要更多。

BufferedImage originalImage = getGrayScale(img.getBufferedImage());//returns an 8-bit unsigned grayscale conversion of the original image

byte[] imageInByte = ((DataBufferByte) originalImage.getRaster().getDataBuffer()).getData();

String binary = toBinary(imageInByte); //converts to a String representation of the binary bits

char[] binCharArray = binary.toCharArray();

BitSet bits = new BitSet(binCharArray.length);

for (int i = 0; i < binCharArray.length; i++) {

if (binCharArray[i] == '1') {

bits.set(i);

}

}

imageInByte = bits.toByteArray();

byte[] high = new byte[(int) imageInByte.length/2];

byte[] low = new byte[(int) imageInByte.length/2];

int highC = 0;

int lowC = 0;

boolean change = false; //start out storing in the high bit

//change will = true on very first run. While true, load in the high byte array. Else low byte

for(int i = 0; i < imageInByte.length; i++){

if(i % 4 == 0){

change = !change;

}

if(change){

high[highC] = imageInByte[i];

highC++;

} else {

low[lowC] = imageInByte[i];

lowC++;

}

}

//old code from a previous attempt.

// for (int j = 0; j < imageInByte.length; j++) {

//       byte h = (byte) (imageInByte[j] & 0xFF);

//       byte l = (byte) ((imageInByte[j] >> 8) & 0xFF);

//       high[j] = h;

//       low[j] = l;

// }

OutputStream out = null;

//add this array to the image array. It goes at the beginning.

byte[] tagBytes = dicomTags.getBytes();

currProcessingImageTagLength = tagBytes.length;

imageInByte = new byte[high.length + low.length + tagBytes.length];

System.arraycopy(tagBytes, 0, imageInByte, 0, tagBytes.length);

System.arraycopy(high, 0, imageInByte, tagBytes.length, high.length);

System.arraycopy(low, 0, imageInByte, tagBytes.length + high.length, low.length);

BufferedImage bImageFromConvert = new BufferedImage(dimWidth, dimHeight, BufferedImage.TYPE_BYTE_GRAY);//dimWidth and dimHeight are the image dimensions, stored much earlier in this function

byte[] bufferHolder = ((DataBufferByte) bImageFromConvert.getRaster().getDataBuffer()).getData();

System.arraycopy(imageInByte, 0, bufferHolder, 0, bufferHolder.length);

//This is where I try and write the final image before sending it off to an image compressor

ImageIO.write(bImageFromConvert,"bmp", new File(

directory + fileName +"_Compressed.bmp"));

return new File(directory + fileName +"_Compressed.bmp");

下面是您感兴趣的toBinary函数:

private static String toBinary(byte[] bytes) {

StringBuilder sb = new StringBuilder(bytes.length * Byte.SIZE);

for (int i = 0; i < Byte.SIZE * bytes.length; i++) {

sb.append((bytes[i / Byte.SIZE] << i % Byte.SIZE & 0x80) == 0 ? '0' : '1');

}

return sb.toString();

}

非常感谢你的帮助!我现在已经花费了将近20个小时来尝试解决这一问题。这是一个巨大的头痛,您的任何见解都将不胜感激。

编辑:这是getGreyScale函数:

public static BufferedImage getGrayScale(BufferedImage inputImage) {

BufferedImage img = new BufferedImage(inputImage.getWidth(), inputImage.getHeight(), BufferedImage.TYPE_BYTE_GRAY);

Graphics g = img.getGraphics();

g.drawImage(inputImage, 0, 0, null);

g.dispose();

return img;

}

编辑2:我已应要求添加了一些图像。

电流输出:

当前图像

请注意,由于信誉低于10,所以无法发布具有"预期的"高字节和低字节结果的图像。

a)"将图像矩阵"拆分",其上半部分包含所有高字节,下半部分包含所有低字节。":因此,您希望将所有字节的高部分捆绑在一起 图片的一部分? 预期的结果是什么? b)也许这与dicom有关,我对此一无所知,但被认为是简单的处理步骤,应该可以理解您的期望和所得到的

@gpasch a)是的。 图像应该出现,所有高字节都在顶部,而所有低字节都在底部。 换句话说,最终图像应为原始尺寸,但是图像的上半部分为迷你明亮图像,而下半部分为迷你深色图像。 b)出于所有意图和目的,在处理DICOM时,它应具有正常的bmp的功能。

这表示每4个字节更改一次; 那不是您想要的:

for(int i = 0; i < imageInByte.length; i++){

if(i % 4 == 0){

change = !change;

}

if(change){

high[highC] = imageInByte[i];

highC++;

} else {

low[lowC] = imageInByte[i];

lowC++;

}

}

根据您较早的尝试,我将以此替换它

for (int j = 0; j < imageInByte.length; j+=2) {

byte h = (byte) (imageInByte[j] & 0xF0);

byte h2 = (byte) (imageInByte[j+1] & 0xF0);

byte l = (byte) (imageInByte[j] & 0x0f);

byte l2 = (byte) (imageInByte[j+1] & 0x0f);

high[j/2] = h|(h2>>4);

low[j/2] = (l<<4)|l2;

}

嗯,它看起来确实很接近我需要的东西,但是还差一点。让我浏览一下代码,确保其不是Im正在执行的操作。

灰色的第一部分我不知道它是如何工作的以及它是否正确;然后中间有很多摆弄的东西-您有二进制文件,我不知道为什么需要所有这些东西到String并返回-最后,您可以尝试在压缩等之前将图像显示为JFrame,以确保它是视觉上您的期望

在问题中添加了功能,以便您查看。我不确定我是否需要琴弦和琴背部分。我只是不太清楚Java如何处理二进制位,或者它是否处理二进制位,我想确定一下。您认为它会禁止我的代码吗?

我将检查代码,然后再看它如何工作-它不会抑制可能只是隐藏一些错误的可能

我不知道您为什么说"有点不对劲"-在这里似乎对我有用(我排除了我不想要并且不会弄乱的dicom标签)-否则张贴示例图像来说明您的期望-一切顺利

好的,我在修改后添加了当前输出。正如我在编辑中说的那样,我无法发布"预期"图像,因为堆栈溢出将不允许其他链接。如果您需要这些图像,我可以尝试将所有内容与屏幕快照或mspaint一起打包。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值