前言
在最近的一个项目需要用java来解析dicom图片,dicom被广泛应用于放射医疗,心血管成像以及放射诊疗诊断设备(x射线,ct,核磁共振,超声等),并且在眼科和牙科等其它医学领域得到越来越深入广泛的应用,在实现中遇到一些问题下面做一些记录。
首先找一个*.dcm文件。用编辑器打开可以看到如下界面。我是用的编辑器是ultraedit
红字标注的是字节码的标注,前面8行代码是文件的头信息一般没用。从第九行开始的四个十六进制数“44,49,43,4d”是很重要的。用ascll码解释就是dicm。表示这是一个dicom文件,这四个16进制数如果丢失或损坏,这个dicom图片就无法打开了。
下面用java来读取这些十六进制数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import java.io.file; import java.io.fileinputstream; import java.io.filenotfoundexception; import java.io.ioexception; public class my_dicom { static fileinputstream input; static byte [] b; public static void main(string[] args) { try { file file = new file( "g:/zzz.dcm" ); input = new fileinputstream(file); b = new byte [( int ) file.length()]; input.read(b); } catch (filenotfoundexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } init(); } public static void init(){ system.out.println( "b.length=" +b.length); for ( int i = 0 ;i< 10000 ;i++) { system.out.print(integer.tohexstring(b[i])); if (i% 16 == 15 ) { system.out.println(); } else { system.out.print( ", " ); } } } } |
(因为文件太大有13万个字节,所以为了展示只循环1万次。读取前一万个字节)
上面的代码很普通就是将文件流读入byte数组中。用integer.tohexstring(b[i])
将其转化成十六进制。
问题出现了。
运行后:
对照上面的编辑器打开的十六进制列表红字处本该是a6可是却打印出了ffffffa6。
查找问题
笔算出错字节所在的位置是140。打印system.out.pritln(b[140]);
结果是-90。为什么是-90?。
反向推到a6转化为十进制应该是166。
好了这些找到问题了。166+90=256这不是巧合。忽略了一个问题就是byte数组的最大值只有127.所以文件中读到的数组大于127时byte数组的读取就会出错。
解决方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public static void init(){ system.out.println( "b.length=" +b.length); for ( int i = 0 ;i< 10000 ;i++) { if (b[i]< 0 ) { int temp=b[i]+ 256 ; system.out.print(integer.tohexstring(temp)); } else { system.out.print(integer.tohexstring(b[i])); } if (i% 16 == 15 ) { system.out.println(); } else { system.out.print( ", " ); } } } |
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:http://blog.csdn.net/kerrigeng/article/details/53519584