bigdataviewer / bigdataviewer-core

ImgLib2-based viewer for registered SPIM stacks and more
BSD 2-Clause "Simplified" License
34 stars 35 forks source link

MultiResolutionRenderer creates new images with every paint request if highest screen scale is not 1 #48

Closed hanslovsky closed 6 years ago

hanslovsky commented 6 years ago

The width/height check in MultiResolutionRenderer.checkResize compares the width/height of the image scaled by the screen scale to the component width/height

if (screenImages[0][0] == null
        || width.applyAsInt(screenImages[0][0]) * screenScales[0] != componentW
        || height.applyAsInt(screenImages[0][0]) * screenScales[0] != componentH)

when instead, it should compare the width/height of the image compared to the scaled component width height:

if (screenImages[0][0] == null
        || width.applyAsInt(screenImages[0][0]) != (int)(componentW * screenScales[0])
        || height.applyAsInt(screenImages[0][0]) != (int)(componentH * screenScales[0]))

As a result, when screenScales[0] != 1.0, new images are created with every paint request. To re-produce, modify MultiResolutionRenderer.checkResize to:

final double screenToViewerScale = screenScales[ i ];
final int w = ( int ) ( screenToViewerScale * componentW );
final int h = ( int ) ( screenToViewerScale * componentH );
System.out.println(String.format("Resizing images: w=%d (%d), h=%d (%d) for scale %f", w, componentW, h, componentH, screenToViewerScale));

and run this main method:

public static void main(String[] args) {
    ArrayImg<UnsignedByteType, ByteArray> rai = ArrayImgs.unsignedBytes(100, 200, 300);
    new Random(100).nextBytes(rai.update(null).getCurrentStorageArray());
    BdvFunctions.show(rai, "noise", BdvOptions.options().screenScales(new double[] {0.5, 0.25, 0.125}));
}
hanslovsky commented 6 years ago

See also saalfeldlab/paintera#143