最近看到群里很多小伙伴比较关心dcm文件怎么转jpg或者是bmp文件,其实在dcm4chee中是提供了很多的方法,但是我们真正在用的时候其实重点还是在dcm文件本身,如果是经过压缩的文件,你用传统方法就没法去结项,如果是彩色的图片,你就蒙了,那么就这些问题给大家提供几种解析方式:
一、传统转化-----使用dcm2jpg
导入jar包依赖:
代码:
package com.company.dicom.utils;
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.List;
import javax.imageio.IIOException;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import org.dcm4che2.data.DicomObject;
import org.dcm4che2.imageio.plugins.dcm.DicomImageReadParam;
import org.dcm4che2.util.CloseUtils;
//实际上这是重写了Dcm2Jpg
public class Dcm2Jpg2
{
private static final String USAGE = "dcm2jpg [Options]
private static final String DESCRIPTION = "Convert DICOM image(s) to JPEG(s)\nOptions:";
private static final String EXAMPLE = null;
private int frame = 1;
private float center;
private float width;
private String vlutFct;
private boolean autoWindowing;
private DicomObject prState;
private short[] pval2gray;
private String formatName = "JPEG";
private String compressionType = "jpeg";
private String fileExt = ".jpg";
private Float imageQuality;
private String imageWriterClassname;
private void setFrameNumber(int frame)
{
this.frame = frame;
}
private void setWindowCenter(float center) {
this.center = center;
}
private void setWindowWidth(float width) {
this.width = width;
}
public final void setVoiLutFunction(String vlutFct) {
this.vlutFct = vlutFct;
}
private final void setAutoWindowing(boolean autoWindowing) {
this.autoWindowing = autoWindowing;
}
private final void setPresentationState(DicomObject prState) {
this.prState = prState;
}
private final void setPValue2Gray(short[] pval2gray) {
this.pval2gray = pval2gray;
}
public final void setFileExt(String fileExt) {
this.fileExt = fileExt;
}
private void setImageWriter(String imagewriter) {
this.imageWriterClassname = imagewriter;
}
public void setFormatName(String formatName) {
this.formatName = formatName;
}
private void setImageQuality(int quality) {
this.imageQuality = new Float(quality / 100.0F);
}
private ImageWriter getImageWriter(String imageWriterClass) throws IIOException
{
Iterator it = ImageIO.getImageWritersByFormatName(this.formatName);
while (it
.hasNext()) {
ImageWriter writer = (ImageWriter)it.next();
if (("*".equals(imageWriterClass)) ||
(writer.getClass().getName().equals(imageWriterClass))) {
return writer;
}
}
throw new IIOException("No such ImageWriter - " + imageWriterClass);
}
public void setCompressionType(String compressionType) {
this.compressionType = compressionType;
}
public void convert(Object src, File dest) throws IOException {
Iterator iter = ImageIO.getImageReadersByFormatName("DICOM");
ImageReader reader = (ImageReader)iter.next();
DicomImageReadParam param = (DicomImageReadParam)reader
.getDefaultReadParam();
param.setWindowCenter(this.center);
param.setWindowWidth(this.width);
param.setVoiLutFunction(this.vlutFct);
param.setPresentationState(this.prState);
param.setPValue2Gray(this.pval2gray);
param.setAutoWindowing(this.autoWindowing);
ImageInputStream iis = ImageIO.createImageInputStream(src);
try {
reader.setInput(iis, false);
BufferedImage bi = reader.read(this.frame - 1, param);
if (bi == null) {
System.out.println("\nError: " + src + " - couldn't read!");
return;
}
if (this.imageWriterClassname == null)
encodeByJPEGEncoder(bi, dest);
else
encodeByImageIO(bi, dest);
} finally {
CloseUtils.safeClose(iis); } CloseUtils.safeClose(iis);
System.out.print('.');
}
private void encodeByJPEGEncoder(BufferedImage bi, File dest) throws ImageFormatException, IOException
{
OutputStream out = null;
try {
out = new BufferedOutputStream(new FileOutputStream(dest));
JPEGImageEncoder enc = JPEGCodec.createJPEGEncoder(out);
if (this.imageQuality != null) {
JPEGEncodeParam param = JPEGCodec.getDefaultJPEGEncodeParam(bi);
param.setQuality(this.imageQuality.floatValue(), true);
enc.setJPEGEncodeParam(param);
}
enc.encode(bi);
} finally {
CloseUtils.safeClose(out);
}
}
private void encodeByImageIO(BufferedImage bi, File dest) throws IOException
{
ImageWriter writer = getImageWriter(this.imageWriterClassname);
ImageOutputStream out = null;
try {
out = ImageIO.createImageOutputStream(dest);
writer.setOutput(out);
ImageWriteParam iwparam = writer.getDefaultWriteParam();
if (iwparam.canWriteCompressed()) {
iwparam.setCompressionMode(2);
String[] compressionTypes = iwparam.getCompressionTypes();
if ((compressionTypes != null) &&
(compressionTypes.length > 0) && (
(this.compressionType != null) ||
(iwparam
.getCompressionType() == null))) {
for (int i = 0; i < compressionTypes.length; i++) {
if ((this.compressionType == null) ||
(compressionTypes[i]
.compareToIgnoreCase(this.compressionType) == 0)) {
iwparam.setCompressionType(compressionTypes[i]);
break;
}
}
}
if (this.imageQuality != null)
iwparam.setCompressionQuality(this.imageQuality
.floatValue());
} else if (this.imageQuality != null) {
System.out
.println("Selected Image Writer can not compress! imageQuality is ignored!");
}
writer.write(null, new IIOImage(bi, null, null), iwparam);
} finally {
CloseUtils.safeClose(out);
writer.dispose();
}
}
public int mconvert(List
{
int count = 0;
int i = optind;
for (int n = args.size() - 1; i < n; i++) {
File src = new File((String)args.get(i));
count += mconvert(src, new File(destDir, src2dest(src)));
}
return count;
}
private String src2dest(File src) {
String srcname = src.getName();
return src.isFile() ? srcname + this.fileExt : srcname;
}
public int mconvert(File src, File dest) throws IOException {
if (!src.exists()) {
System.err.println("WARNING: No such file or directory: " + src +
" - skipped.");
return 0;
}
if (src.isFile()) {
try {
convert(src, dest);
} catch (Exception e) {
System.err.println("WARNING: Failed to convert " + src + ":");
e.printStackTrace(System.err);
System.out.print('F');
return 0;
}
System.out.print('.');
return 1;
}
File[] files = src.listFiles();
if ((files.length > 0) && (!dest.exists())) {
dest.mkdirs();
}
int count = 0;
for (int i = 0; i < files.length; i++) {
count += mconvert(files[i], new File(dest, src2dest(files[i])));
}
return count;
}
}
另一种简单地方法直接调用dcm2jpg的convert方法:
package com.company.dicom.module;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.dcm4che2.tool.dcm2jpg.Dcm2Jpg;
import com.iflytek.dicom.config.GlobalConfig;
import com.iflytek.dicom.utils.StringUtils;
/**
*
* ClassName: DicomToJpg
*
* @Description: 从ftp下载文件解压并转换
* @author wangyl
* @date 2016年8月19日
*/
public class DicomToJpg {
private static Logger logger = LogManager.getLogger(DicomToJpg.class.getName());
/**
*
* @Description: 解压文件流进行处理 .PK文件解压处理为jpg
* @param @param inputStream
* @param @param outputPath
* @return void
* @throws Exception
* @throws
* @author wangyl
* @date 2016年9月14日
*/
public File convert(File file, String outputPath) throws Exception {
File outFile =null;
try {
Dcm2Jpg dcm2Jpg = new Dcm2Jpg();
try {
dcm2Jpg.convert(file, new File(outputPath));
outFile= new File(outputPath);
deleteFile(file);
} catch (Exception e) {
throw new Exception();
}
} catch (Exception e) {
throw new Exception();
}
return outFile;
}
//递归删除文件夹
private void deleteFile(File file) {
if (file.exists()) {
file.delete();//删除文件
File partFile =new File(file.getParent());
if(partFile.exists()){
partFile.delete();
}else {
logger.error("所删除的文件不存在");
}
}else {
logger.error("所删除的文件不存在");
}
}
public String downFileFromDicom(File file) {
String localFile = GlobalConfig.getString("pacsUrl")+ file.getName().concat(".jpg");
Dcm2Jpg dcm2Jpg = new Dcm2Jpg();
try {
dcm2Jpg.convert(file, new File(localFile));
} catch (Exception e) {
e.printStackTrace();
}
//删除原始图
file.delete();
return localFile;
}
}
二、dcm转bmp(含压缩图像),需要依赖dll文件,附件有
public class DicomParse {
public long mInst = 0;
//图像的裸数据
public int width = 0;
public int height = 0;
public short[] imgData;
//bmp的内存
public byte[] bmpData;
public int bmpSize;
static {
System.loadLibrary("DicomParsejni");
}
/*JnniIdicomInit 初始化函数
*参数 path:传入DicomParse.dll的路径*/
public native static int ninit(String path);
/* JniIdicomUinit 逆初始化 */
public native static int nuninit();
/* JniIdicomCreateInst 创建实例 */
public native int ncreate();
/*JniIdicomDestoryInst 销毁实例 */
public native int ndestory();
/*JniIdicomReset 重置实例 */
public native int nreset();
/*JniIdicomLoadFile 输入dcm文件
* 参数 path:dcm文件的路径 */
public native int nloadpath(String path);
/*jniIdicomLoadBuf 输入dcm的数据buffer
* 参数data:buffer数组
* 参数size:buffer大小*/
public native int nloadbuff(byte[] data, int size);
//获得对应tag的数值
public native String ngettag(String label);
//获得图像裸数据
public native int ngetdata();
//获取bmp的内存和大小
public native int ngetbmp();
}
public class Test {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
int ret = DicomParse.ninit("DicomParse.dll");
if (ret>0) {
}
//m只容许一个线程内调用,多线程需要new多个
DicomParse m = new DicomParse();
//创建
m.ncreate();
File sourceDir=new File("D:\\dcm");
File[] files =sourceDir.listFiles();
for(File file:files)
{
m.nreset();
//加载
m.nloadpath(file.getAbsolutePath());
//获得裸数据
m.ngetdata();
System.out.println(m.imgData.length);
System.out.println(m.width);
System.out.println(m.height);
//获得tag
String studyid = m.ngettag("0020|0010");
String name = m.ngettag("0010|0010");
System.out.println(name +" " + studyid );
//获得bmp
m.ngetbmp();
System.out.println(m.bmpData.length);
System.out.println(m.bmpSize);
FileOutputStream outputStream = new FileOutputStream(
sourceDir.getAbsolutePath()+File.separator+file.getName()+".jpg", false);
outputStream.write(m.bmpData);
System.out.println("bmpData:"+m.bmpData.length);
outputStream.close();
//删除源文件
if (m.bmpData.length>0) {
//file.deleteOnExit();
}
}
//销毁实例
m.ndestory();
//释放
DicomParse.nuninit();
}
三、借助于第三方jar包--clibwrapper_jiio-1.2-pre-dr-b04.jar
解决方案:
1.安装32为的JDK。应为对应的DLL现在只有32位的。
2.新增clib_jiio-1.2-pre-dr-b04.zip包中的DLL文件。到JDK的bin目录下
3.新增依赖JAR包clibwrapper_jiio-1.2-pre-dr-b04.jar。
package com.iflytek.dicom;
import com.sun.media.imageioimpl.common.PackageUtil;
import com.sun.medialib.codec.jiio.codecLibI18N;
import org.dcm4che2.tool.dcm2jpg.Dcm2Jpg;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.AccessController;
import java.security.PrivilegedAction;
public class Dicom2Jpg {
public static void main(String[] args) {
Dcm2Jpg dcm2Jpg = new Dcm2Jpg();
String inPath = "F:\\DiCOM\\dicom\\dicom\\DICOM\\xuanwu-A170206091723327\\1.3.12.2.1107.5.1.4.75552.30000017020102440020400202861";
String outPath = "F:\\DiCOM\\dicom\\dicom\\DICOM\\out";
System.loadLibrary("clib_jiio");//测试是否能加载
try {
if(!(new File(outPath)).exists()) {
(new File(outPath)).mkdirs();
if(!(new File(outPath + "\\3.jpg")).exists()) {
(new File(outPath + "\\3.jpg")).createNewFile();
}
}
try {
dcm2Jpg.convert(new File(inPath), new File(outPath + "\\3.jpg"));
} catch (IOException var5) {
var5.printStackTrace();
}
} catch (IOException var6) {
var6.printStackTrace();
}
}
}