weasis 载入影像流程分析

View2d

    @Override
    protected void setImage(DicomImageElement img) {
        boolean newImg = img != null && !img.equals(imageLayer.getSourceImage());
        if (newImg) {
            deletePrLayers();
            PrGraphicUtil.applyPresentationModel(img);
        }
        super.setImage(img);

        updatePrButtonState(img, newImg);
        if (newImg) {
            updateKOselectedState(img);
        }
    }

DefaultView2d

    protected void setImage(E img) {
        boolean updateGraphics = false;
        imageLayer.setEnableDispOperations(false);
        if (img == null) {
            actionsInView.put(ActionW.SPATIAL_UNIT.cmd(), Unit.PIXEL);
            ActionState spUnitAction = eventManager.getAction(ActionW.SPATIAL_UNIT);
            if (spUnitAction instanceof ComboItemListener) {
                ((ComboItemListener) spUnitAction)
                    .setSelectedItemWithoutTriggerAction(actionsInView.get(ActionW.SPATIAL_UNIT.cmd()));
            }
            // Force the update for null image
            imageLayer.setEnableDispOperations(true);
            imageLayer.setImage(null, null);
            imageLayer.setEnableDispOperations(false);

            setGraphicManager(new XmlGraphicModel());
            closeLens();
        } else {
            E oldImage = imageLayer.getSourceImage();
            if (img != null && !img.equals(oldImage)) {
                updateGraphics = true;
                actionsInView.put(ActionW.SPATIAL_UNIT.cmd(), img.getPixelSpacingUnit());
                if (eventManager.getSelectedViewPane() == this) {
                    ActionState spUnitAction = eventManager.getAction(ActionW.SPATIAL_UNIT);
                    if (spUnitAction instanceof ComboItemListener) {
                        ((ComboItemListener) spUnitAction)
                            .setSelectedItemWithoutTriggerAction(actionsInView.get(ActionW.SPATIAL_UNIT.cmd()));
                    }
                }
                actionsInView.put(ActionW.PREPROCESSING.cmd(), null);
                ActionState spUnitAction = eventManager.getAction(ActionW.SPATIAL_UNIT);
                if (spUnitAction instanceof ComboItemListener) {
                    ((ComboItemListener) spUnitAction)
                        .setSelectedItemWithoutTriggerAction(actionsInView.get(ActionW.SPATIAL_UNIT.cmd()));
                }

                updateCanvas(img, false);

                imageLayer.fireOpEvent(new ImageOpEvent(ImageOpEvent.OpEvent.ImageChange, series, img, null));
                resetZoom();
                // Update zoom operation to the current image (Reset update to the previous one)
                ImageOpNode node = imageLayer.getDisplayOpManager().getNode(ZoomOp.OP_NAME);
                if (node != null) {
                    double viewScale = getViewModel().getViewScale();
                    node.setParam(ZoomOp.P_RATIO_X, viewScale * img.getRescaleX());
                    node.setParam(ZoomOp.P_RATIO_Y, viewScale * img.getRescaleY());
                }
                imageLayer.setImage(img, (OpManager) actionsInView.get(ActionW.PREPROCESSING.cmd()));

                if (AuditLog.LOGGER.isInfoEnabled()) {
                    PlanarImage image = img.getImage();
                    if (image != null) {
                        StringBuilder pixSize = new StringBuilder();
                        SampleModel sm = image.getSampleModel();
                        if (sm != null) {
                            int[] spsize = sm.getSampleSize();
                            if (spsize != null && spsize.length > 0) {
                                pixSize.append(spsize[0]);
                                for (int i = 1; i < spsize.length; i++) {
                                    pixSize.append(',');
                                    pixSize.append(spsize[i]);
                                }
                            }
                        }
                        AuditLog.LOGGER.info("open:image size:{},{} depth:{}", //$NON-NLS-1$
                            new Object[] { image.getWidth(), image.getHeight(), pixSize.toString() });
                    }
                }
            }
            // Apply all image processing operation for visualization
            imageLayer.setEnableDispOperations(true);

            if (updateGraphics) {
                GraphicModel modelList = (GraphicModel) img.getTagValue(TagW.PresentationModel);
                // After getting a new image iterator, update the measurements
                if (modelList == null) {
                    modelList = new XmlGraphicModel(img);
                    img.setTag(TagW.PresentationModel, modelList);
                }
                setGraphicManager(modelList);
            }

            if (panner != null) {
                panner.updateImage();
            }
            if (lens != null) {
                lens.updateImage();
                lens.updateZoom();
            }
        }
    }

RenderedImageLayer


    @Override
    public void setImage(E image, OpManager preprocessing) {
        boolean init = (image != null && !image.equals(this.sourceImage)) || (image == null && sourceImage != null);
        this.sourceImage = image;

        this.preprocessing = preprocessing;
        if (preprocessing != null || init) {
            disOpManager.setFirstNode(getSourceRenderedImage());
            updateDisplayOperations();
        }
    }
    @Override
    public RenderedImage getSourceRenderedImage() {
        if (sourceImage != null) {
            return sourceImage.getImage(preprocessing);
        }
        return null;
    }
ImageElement
    public PlanarImage getImage(OpManager manager) {
        return getImage(manager, true);
    }
    public synchronized PlanarImage getImage(OpManager manager, boolean findMinMax) {
        try {
            return getCacheImage(startImageLoading(), manager, findMinMax);
        } catch (OutOfMemoryError e1) {
            /*
             * Appends when loading a big image without tiling, the memory left is not enough for the renderedop (like
             * Extrema)
             */
            LOGGER.warn("Out of MemoryError: {}", this, e1); //$NON-NLS-1$
            mCache.expungeStaleEntries();
            System.gc();
            System.gc();
            try {
                Thread.sleep(100);
            } catch (InterruptedException et) {
                // Do nothing
            }
            return getCacheImage(startImageLoading(), manager, findMinMax);
        }
    }
    private PlanarImage startImageLoading() throws OutOfMemoryError {
        PlanarImage cacheImage;
        if ((cacheImage = mCache.get(this)) == null && readable && setAsLoading()) {
            LOGGER.debug("Asking for reading image: {}", this); //$NON-NLS-1$
            Load ref = new Load();
            Future<PlanarImage> future = IMAGE_LOADER.submit(ref);
            PlanarImage img = null;
            try {
                img = future.get();

            } catch (InterruptedException e) {
                // Re-assert the thread's interrupted status
                Thread.currentThread().interrupt();
                // We don't need the result, so cancel the task too
                future.cancel(true);
            } catch (ExecutionException e) {
                if (e.getCause() instanceof OutOfMemoryError) {
                    setAsLoaded();
                    throw (OutOfMemoryError) e.getCause();
                } else {
                    readable = false;
                    LOGGER.error("Cannot read pixel data!: {}", this, e); //$NON-NLS-1$
                }
            }
            if (img != null) {
                readable = true;
                mCache.put(this, img);
                cacheImage = img;
                this.setTag(TagW.ImageCache, true);
            }
            setAsLoaded();
        }
        return cacheImage;
    }
    public static final ExecutorService IMAGE_LOADER = ThreadUtil.buildNewSingleThreadExecutor("Image Loader");
    class Load implements Callable<PlanarImage> {

        @Override
        public PlanarImage call() throws Exception {
            return loadImage();
        }
    }
    protected PlanarImage loadImage() throws Exception {
        return mediaIO.getImageFragment(this);
    }
DicomMediaIO
    @Override
    public PlanarImage getImageFragment(MediaElement media) throws Exception {
        if (media != null && media.getKey() instanceof Integer && isReadableDicom()) {
            int frame = (Integer) media.getKey();
            if (frame >= 0 && frame < numberOfFrame && hasPixel) {
                // read as tiled rendered image
                LOGGER.debug("Start reading dicom image frame: {} sopUID: {}", //$NON-NLS-1$
                    frame, TagD.getTagValue(this, Tag.SOPInstanceUID));
                return getValidImage(readAsRenderedImage(frame, null), media);
            }
        }
        return null;
    }
    @Override
    public RenderedImage readAsRenderedImage(int frameIndex, ImageReadParam param) throws IOException {
        readingImage = true;
        try {
            readMetaData(true);
            checkIndex(frameIndex);
            if (param == null) {
                param = getDefaultReadParam();
            }

            RenderedImage bi;
            if (decompressor != null) {
                decompressor.setInput(iisOfFrame(frameIndex));
                if (isRLELossless() && (pmi.isSubSambled() || pmi.name().startsWith("YBR"))) { //$NON-NLS-1$
                    bi = convertSubSambledAndYBR(frameIndex, param);
                } else {
                    bi = decompressor.readAsRenderedImage(0, decompressParam(param));
                }
            } else {
                // Rewrite image with subsampled model (otherwise cannot not be displayed as RenderedImage)
                // Convert YBR_FULL into RBG as the ybr model is not well supported.
                if (pmi.isSubSambled() || pmi.name().startsWith("YBR")) { //$NON-NLS-1$
                    bi = convertSubSambledAndYBR(frameIndex, param);
                } else {
                    ImageReader reader = initRawImageReader();
                    bi = reader.readAsRenderedImage(frameIndex, param);
                }
            }
            return validateSignedShortDataBuffer(bi);
        } finally {
            /*
             * "readingImage = false" will close the stream of the tiled image. The problem is that
             * readAsRenderedImage() do not read data immediately: RenderedImage delays the image reading
             */
        }
    }
    private PlanarImage getValidImage(RenderedImage buffer, MediaElement media) {
        PlanarImage img = null;
        if (buffer != null) {
            // Bug fix: CLibImageReader and J2KImageReaderCodecLib (imageio libs) do not handle negative values
            // for short data. They convert signed short to unsigned short.
            if (dataType == DataBuffer.TYPE_SHORT && buffer.getSampleModel().getDataType() == DataBuffer.TYPE_USHORT) {
                img = RectifyUShortToShortDataDescriptor.create(buffer, LayoutUtil.createTiledLayoutHints(buffer));
            } else if (ImageUtil.isBinary(buffer.getSampleModel())) {
                ParameterBlock pb = new ParameterBlock();
                pb.addSource(buffer);
                // Tile size are set in this operation
                img = JAI.create("formatbinary", pb, null); //$NON-NLS-1$
            } else if (buffer.getTileWidth() != ImageFiler.TILESIZE || buffer.getTileHeight() != ImageFiler.TILESIZE) {
                img = ImageFiler.tileImage(buffer);
            } else {
                img = NullDescriptor.create(buffer, LayoutUtil.createTiledLayoutHints(buffer));
            }

            /*
             * Handle overlay in pixel data: extract the overlay, serialize it in a file and set all values to O in the
             * pixel data.
             */
            Integer overlayBitMask = (Integer) getTagValue(TagW.OverlayBitMask);
            if (overlayBitMask != null) {
                if (media.getTagValue(TagW.OverlayBurninDataPath) == null) {
                    // Serialize overlay (from pixel data)
                    Attributes ds = getDicomObject();
                    int[] embeddedOverlayGroupOffsets = Overlays.getEmbeddedOverlayGroupOffsets(ds);

                    if (embeddedOverlayGroupOffsets.length > 0) {
                        FileOutputStream fileOut = null;
                        ObjectOutput objOut = null;
                        try {
                            byte[][] overlayData = new byte[embeddedOverlayGroupOffsets.length][];
                            Raster raster = buffer.getData();
                            for (int i = 0; i < embeddedOverlayGroupOffsets.length; i++) {
                                overlayData[i] =
                                    OverlayUtils.extractOverlay(embeddedOverlayGroupOffsets[i], raster, ds);
                            }
                            File file = File.createTempFile("ovly_", "", AppProperties.FILE_CACHE_DIR); //$NON-NLS-1$ //$NON-NLS-2$
                            fileOut = new FileOutputStream(file);
                            objOut = new ObjectOutputStream(fileOut);
                            objOut.writeObject(overlayData);
                            media.setTag(TagW.OverlayBurninDataPath, file.getPath());
                        } catch (Exception e) {
                            LOGGER.error("Cannot serialize overlay", e); //$NON-NLS-1$
                        } finally {
                            FileUtil.safeClose(objOut);
                            FileUtil.safeClose(fileOut);
                        }
                    }
                }
                // Set to 0 all bits outside bitStored
                img = AndConstDescriptor.create(img, new int[] { overlayBitMask }, null);
            }
            img = DicomImageUtils.getRGBImageFromPaletteColorModel(img, getDicomObject());
        }
        return img;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值