Search in sources :

Example 61 with Patch

use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.

the class FSLoader method generateMipMaps.

/**
 * Given an image and its source file name (without directory prepended), generate
 * a pyramid of images until reaching an image not smaller than 32x32 pixels.
 * <p>
 * Such images are stored as jpeg 85% quality in a folder named trakem2.mipmaps.
 * </p>
 * <p>
 * The Patch id and the right extension will be appended to the filename in all cases.
 * </p>
 * <p>
 * Any equally named files will be overwritten.
 * </p>
 */
protected boolean generateMipMaps(final Patch patch) {
    Utils.log2("mipmaps for " + patch);
    final String path = getAbsolutePath(patch);
    if (null == path) {
        Utils.log("generateMipMaps: null path for Patch " + patch);
        cannot_regenerate.add(patch);
        return false;
    }
    if (hs_unloadable.contains(patch)) {
        FilePathRepair.add(patch);
        return false;
    }
    synchronized (gm_lock) {
        try {
            if (null == dir_mipmaps)
                createMipMapsDir(null);
            if (null == dir_mipmaps || isURL(dir_mipmaps))
                return false;
        } catch (Exception e) {
            IJError.print(e);
        }
    }
    /**
     * Record Patch as modified
     */
    touched_mipmaps.add(patch);
    /**
     * Remove serialized features, if any
     */
    removeSerializedFeatures(patch);
    /**
     * Remove serialized pointmatches, if any
     */
    removeSerializedPointMatches(patch);
    /**
     * Alpha mask: setup to check if it was modified while regenerating.
     */
    final long alpha_mask_id = patch.getAlphaMaskId();
    final int resizing_mode = patch.getProject().getMipMapsMode();
    try {
        ImageProcessor ip;
        ByteProcessor alpha_mask = null;
        ByteProcessor outside_mask = null;
        int type = patch.getType();
        // Aggressive cache freeing
        releaseToFit(patch.getOWidth() * patch.getOHeight() * 4 + MIN_FREE_BYTES);
        // Obtain an image which may be coordinate-transformed, and an alpha mask.
        Patch.PatchImage pai = patch.createTransformedImage();
        if (null == pai || null == pai.target) {
            Utils.log("Can't regenerate mipmaps for patch " + patch);
            cannot_regenerate.add(patch);
            return false;
        }
        ip = pai.target;
        // can be null
        alpha_mask = pai.mask;
        // can be null
        outside_mask = pai.outside;
        pai = null;
        // Old style:
        // final String filename = new StringBuilder(new File(path).getName()).append('.').append(patch.getId()).append(mExt).toString();
        // New style:
        final String filename = createMipMapRelPath(patch, mExt);
        int w = ip.getWidth();
        int h = ip.getHeight();
        // sigma = sqrt(2^level - 0.5^2)
        // where 0.5 is the estimated sigma for a full-scale image
        // which means sigma = 0.75 for the full-scale image (has level 0)
        // prepare a 0.75 sigma image from the original
        double min = patch.getMin(), max = patch.getMax();
        // (The -1,-1 are flags really for "not set")
        if (-1 == min && -1 == max) {
            switch(type) {
                case ImagePlus.COLOR_RGB:
                case ImagePlus.COLOR_256:
                case ImagePlus.GRAY8:
                    patch.setMinAndMax(0, 255);
                    break;
                // Find and flow through to default:
                case ImagePlus.GRAY16:
                    ((ij.process.ShortProcessor) ip).findMinAndMax();
                    patch.setMinAndMax(ip.getMin(), ip.getMax());
                    break;
                case ImagePlus.GRAY32:
                    ((FloatProcessor) ip).findMinAndMax();
                    patch.setMinAndMax(ip.getMin(), ip.getMax());
                    break;
            }
            // may have changed
            min = patch.getMin();
            max = patch.getMax();
        }
        // Set for the level 0 image, which is a duplicate of the one in the cache in any case
        ip.setMinAndMax(min, max);
        // ImageJ no longer stretches the bytes for ByteProcessor with setMinAndmax
        if (ByteProcessor.class == ip.getClass()) {
            if (0 != min && 255 != max) {
                final byte[] b = (byte[]) ip.getPixels();
                final double scale = 255 / (max - min);
                for (int i = 0; i < b.length; ++i) {
                    final int val = b[i] & 0xff;
                    if (val < min)
                        b[i] = 0;
                    else
                        b[i] = (byte) Math.min(255, ((val - min) * scale));
                }
            }
        }
        // Proper support for LUT images: treat them as RGB
        if (ip.isColorLut() || type == ImagePlus.COLOR_256) {
            ip = ip.convertToRGB();
            type = ImagePlus.COLOR_RGB;
        }
        final int first_mipmap_level_saved = patch.getProject().getFirstMipMapLevelSaved();
        if (Loader.AREA_DOWNSAMPLING == resizing_mode) {
            long t0 = System.currentTimeMillis();
            final ImageBytes[] b = DownsamplerMipMaps.create(patch, type, ip, alpha_mask, outside_mask);
            long t1 = System.currentTimeMillis();
            for (int i = 0; i < b.length; ++i) {
                if (i < first_mipmap_level_saved) {
                    // Ignore level i
                    if (null != b[i])
                        CachingThread.storeForReuse(b[i].c);
                } else {
                    boolean written = mmio.save(getLevelDir(dir_mipmaps, i) + filename, b[i].c, b[i].width, b[i].height, 0.85f);
                    if (!written) {
                        Utils.log("Failed to save mipmap with area downsampling at level=" + i + " for patch " + patch);
                        cannot_regenerate.add(patch);
                        break;
                    }
                }
            }
            long t2 = System.currentTimeMillis();
            System.out.println("MipMaps with area downsampling: creation took " + (t1 - t0) + "ms, saving took " + (t2 - t1) + "ms, total: " + (t2 - t0) + "ms\n");
        } else if (Loader.GAUSSIAN == resizing_mode) {
            if (ImagePlus.COLOR_RGB == type) {
                // TODO releaseToFit proper
                releaseToFit(w * h * 4 * 10);
                final ColorProcessor cp = (ColorProcessor) ip;
                final FloatProcessorT2 red = new FloatProcessorT2(w, h, 0, 255);
                cp.toFloat(0, red);
                final FloatProcessorT2 green = new FloatProcessorT2(w, h, 0, 255);
                cp.toFloat(1, green);
                final FloatProcessorT2 blue = new FloatProcessorT2(w, h, 0, 255);
                cp.toFloat(2, blue);
                FloatProcessorT2 alpha;
                final FloatProcessorT2 outside;
                if (null != alpha_mask) {
                    alpha = new FloatProcessorT2(alpha_mask);
                } else {
                    alpha = null;
                }
                if (null != outside_mask) {
                    outside = new FloatProcessorT2(outside_mask);
                    if (null == alpha) {
                        alpha = outside;
                        alpha_mask = outside_mask;
                    }
                } else {
                    outside = null;
                }
                final String target_dir0 = getLevelDir(dir_mipmaps, 0);
                if (Thread.currentThread().isInterrupted())
                    return false;
                // Generate level 0 first:
                if (0 == first_mipmap_level_saved) {
                    boolean written;
                    if (null == alpha) {
                        written = mmio.save(cp, target_dir0 + filename, 0.85f, false);
                    } else {
                        written = mmio.save(target_dir0 + filename, P.asRGBABytes((int[]) cp.getPixels(), (byte[]) alpha_mask.getPixels(), null == outside ? null : (byte[]) outside_mask.getPixels()), w, h, 0.85f);
                    }
                    if (!written) {
                        Utils.log("Failed to save mipmap for COLOR_RGB, 'alpha = " + alpha + "', level = 0  for  patch " + patch);
                        cannot_regenerate.add(patch);
                    }
                }
                // Generate all other mipmap levels
                // TODO: for best performance, it should start from a direct Gaussian downscaling at the first level to write.
                // the scale level. Proper scale is: 1 / pow(2, k)
                int k = 0;
                do {
                    if (Thread.currentThread().isInterrupted())
                        return false;
                    // 1 - Prepare values for the next scaled image
                    k++;
                    // 2 - Check that the target folder for the desired scale exists
                    final String target_dir = getLevelDir(dir_mipmaps, k);
                    if (null == target_dir)
                        break;
                    // 3 - Blur the previous image to 0.75 sigma, and scale it
                    // will resize 'red' FloatProcessor in place.
                    final byte[] r = gaussianBlurResizeInHalf(red);
                    // idem
                    final byte[] g = gaussianBlurResizeInHalf(green);
                    // idem
                    final byte[] b = gaussianBlurResizeInHalf(blue);
                    // idem
                    final byte[] a = null == alpha ? null : gaussianBlurResizeInHalf(alpha);
                    if (null != outside) {
                        final byte[] o;
                        if (alpha != outside)
                            // idem
                            o = gaussianBlurResizeInHalf(outside);
                        else
                            o = a;
                        // If there was no alpha mask, alpha is the outside itself
                        for (int i = 0; i < o.length; i++) {
                            // TODO I am sure there is a bitwise operation to do this in one step. Some thing like: a[i] &= 127;
                            if ((o[i] & 0xff) != 255)
                                a[i] = 0;
                        }
                    }
                    w = red.getWidth();
                    h = red.getHeight();
                    // 4 - Compose ColorProcessor
                    if (first_mipmap_level_saved < k) {
                        // Skip saving this mipmap level
                        continue;
                    }
                    if (null == alpha) {
                        // 5 - Save as jpeg
                        if (!mmio.save(target_dir + filename, new byte[][] { r, g, b }, w, h, 0.85f)) {
                            Utils.log("Failed to save mipmap for COLOR_RGB, 'alpha = " + alpha + "', level = " + k + " for  patch " + patch);
                            cannot_regenerate.add(patch);
                            break;
                        }
                    } else {
                        if (!mmio.save(target_dir + filename, new byte[][] { r, g, b, a }, w, h, 0.85f)) {
                            Utils.log("Failed to save mipmap for COLOR_RGB, 'alpha = " + alpha + "', level = " + k + " for  patch " + patch);
                            cannot_regenerate.add(patch);
                            break;
                        }
                    }
                } while (// not smaller than 32x32
                w >= 32 && h >= 32);
            } else {
                long t0 = System.currentTimeMillis();
                // Greyscale:
                releaseToFit(w * h * 4 * 10);
                if (Thread.currentThread().isInterrupted())
                    return false;
                final FloatProcessorT2 fp = new FloatProcessorT2((FloatProcessor) ip.convertToFloat());
                if (ImagePlus.GRAY8 == type) {
                    // for 8-bit, the min,max has been applied when going to FloatProcessor
                    // just set it
                    fp.setMinMax(0, 255);
                } else {
                    fp.setMinAndMax(patch.getMin(), patch.getMax());
                }
                // fp.debugMinMax(patch.toString());
                FloatProcessorT2 alpha, outside;
                if (null != alpha_mask) {
                    alpha = new FloatProcessorT2(alpha_mask);
                } else {
                    alpha = null;
                }
                if (null != outside_mask) {
                    outside = new FloatProcessorT2(outside_mask);
                    if (null == alpha) {
                        alpha = outside;
                        alpha_mask = outside_mask;
                    }
                } else {
                    outside = null;
                }
                // the scale level. Proper scale is: 1 / pow(2, k)
                int k = 0;
                do {
                    if (Thread.currentThread().isInterrupted())
                        return false;
                    if (0 != k) {
                        // not doing so at the end because it would add one unnecessary blurring
                        gaussianBlurResizeInHalf(fp);
                        if (null != alpha) {
                            gaussianBlurResizeInHalf(alpha);
                            if (alpha != outside && outside != null) {
                                gaussianBlurResizeInHalf(outside);
                            }
                        }
                    }
                    w = fp.getWidth();
                    h = fp.getHeight();
                    // 1 - check that the target folder for the desired scale exists
                    final String target_dir = getLevelDir(dir_mipmaps, k);
                    if (null == target_dir)
                        break;
                    if (k < first_mipmap_level_saved) {
                        // Skip saving this mipmap level
                        k++;
                        continue;
                    }
                    if (null != alpha) {
                        // If there was no alpha mask, alpha is the outside itself
                        if (!mmio.save(target_dir + filename, new byte[][] { fp.getScaledBytePixels(), P.merge(alpha.getBytePixels(), null == outside ? null : outside.getBytePixels()) }, w, h, 0.85f)) {
                            Utils.log("Failed to save mipmap for GRAY8, 'alpha = " + alpha + "', level = " + k + " for  patch " + patch);
                            cannot_regenerate.add(patch);
                            break;
                        }
                    } else {
                        // 3 - save as 8-bit jpeg
                        if (!mmio.save(target_dir + filename, new byte[][] { fp.getScaledBytePixels() }, w, h, 0.85f)) {
                            Utils.log("Failed to save mipmap for GRAY8, 'alpha = " + alpha + "', level = " + k + " for  patch " + patch);
                            cannot_regenerate.add(patch);
                            break;
                        }
                    }
                    // 4 - prepare values for the next scaled image
                    k++;
                } while (// not smaller than 32x32
                fp.getWidth() >= 32 && fp.getHeight() >= 32);
                long t1 = System.currentTimeMillis();
                System.out.println("MipMaps took " + (t1 - t0));
            }
        } else {
            Utils.log("ERROR: unknown image resizing mode for mipmaps: " + resizing_mode);
        }
        return true;
    } catch (Throwable e) {
        Utils.log("*** ERROR: Can't generate mipmaps for patch " + patch);
        IJError.print(e);
        cannot_regenerate.add(patch);
        return false;
    } finally {
        // flush any cached tiles
        flushMipMaps(patch.getId());
        // flush any cached layer screenshots
        if (null != patch.getLayer()) {
            try {
                patch.getLayer().getParent().removeFromOffscreens(patch.getLayer());
            } catch (Exception e) {
                IJError.print(e);
            }
        }
        // gets executed even when returning from the catch statement or within the try/catch block
        synchronized (gm_lock) {
            regenerating_mipmaps.remove(patch);
        }
        // Has the alpha mask changed?
        if (patch.getAlphaMaskId() != alpha_mask_id) {
            Utils.log2("Alpha mask changed: resubmitting mipmap regeneration for " + patch);
            regenerateMipMaps(patch);
        }
    }
}
Also used : ByteProcessor(ij.process.ByteProcessor) FloatProcessor(ij.process.FloatProcessor) TimeoutException(java.util.concurrent.TimeoutException) ExecutionException(java.util.concurrent.ExecutionException) ImageProcessor(ij.process.ImageProcessor) ColorProcessor(ij.process.ColorProcessor) Patch(ini.trakem2.display.Patch) FloatProcessorT2(ini.trakem2.imaging.FloatProcessorT2)

Example 62 with Patch

use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.

the class FSLoader method updatePaths.

/**
 * For the Patch and for any associated slices if the patch is part of a stack.
 */
private void updatePaths(final Patch patch, final String new_path, final boolean is_stack) {
    synchronized (db_lock) {
        try {
            // ensure the old path is cached in the Patch, to get set as the original if there is no original.
            String old_path = getAbsolutePath(patch);
            if (is_stack) {
                old_path = old_path.substring(0, old_path.lastIndexOf("-----#slice"));
                for (Patch p : patch.getStackPatches()) {
                    long pid = p.getId();
                    String str = ht_paths.get(pid);
                    int isl = str.lastIndexOf("-----#slice=");
                    updatePatchPath(p, new_path + str.substring(isl));
                }
            } else {
                Utils.log2("path to set: " + new_path);
                Utils.log2("path before: " + ht_paths.get(patch.getId()));
                updatePatchPath(patch, new_path);
                Utils.log2("path after: " + ht_paths.get(patch.getId()));
            }
            mawts.updateImagePlusPath(old_path, new_path);
        } catch (Throwable e) {
            IJError.print(e);
        }
    }
}
Also used : Patch(ini.trakem2.display.Patch)

Example 63 with Patch

use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.

the class FSLoader method fetchMipMap.

/**
 * Does the actual fetching of the file. Returns null if the file does not exist.
 *  Does NOT pre-release memory from the cache;
 *  call releaseToFit to do that.
 */
public final MipMapImage fetchMipMap(final Patch patch, int level, final long n_bytes) {
    final int max_level = getHighestMipMapLevel(patch);
    if (level > max_level)
        level = max_level;
    final double scale = Math.pow(2.0, level);
    final String filename = getInternalFileName(patch);
    if (null == filename) {
        Utils.log2("null internal filename!");
        return null;
    }
    // New style:
    final String path = new StringBuilder(dir_mipmaps).append(level).append('/').append(createIdPath(Long.toString(patch.getId()), filename, mExt)).toString();
    if (patch.hasAlphaChannel()) {
        final Image img = mmio.open(path);
        return img == null ? null : new MipMapImage(img, scale, scale);
    } else if (patch.paintsWithFalseColor()) {
        // AKA Patch has a LUT or is LUT image like a GIF
        final Image img = mmio.open(path);
        // considers c_alphas
        return img == null ? null : new MipMapImage(img, scale, scale);
    } else {
        final Image img;
        switch(patch.getType()) {
            case ImagePlus.GRAY16:
            case ImagePlus.GRAY8:
            case ImagePlus.GRAY32:
                // ImageSaver.openGreyJpeg(path);
                img = mmio.openGrey(path);
                return img == null ? null : new MipMapImage(img, scale, scale);
            default:
                // For color images: (considers URL as well)
                img = mmio.open(path);
                // considers c_alphas
                return img == null ? null : new MipMapImage(img, scale, scale);
        }
    }
}
Also used : MipMapImage(ini.trakem2.display.MipMapImage) Image(java.awt.Image) BufferedImage(java.awt.image.BufferedImage) MipMapImage(ini.trakem2.display.MipMapImage)

Example 64 with Patch

use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.

the class FilePathRepair method fixPath.

private static void fixPath(final JTable table, final PathTableModel data, final int row, final boolean fix_similar, final boolean fix_all, final boolean update_mipmaps) throws Exception {
    synchronized (projects) {
        final Patch patch = data.vp.get(row);
        if (null == patch)
            return;
        final String old_path = patch.getImageFilePath();
        final File f = new File(old_path);
        if (f.exists()) {
            Utils.log("File exists for " + patch + " at " + f.getAbsolutePath() + "\n  --> not updating path.");
            data.remove(row);
            return;
        }
        // Else, pop up file dialog
        OpenDialog od = new OpenDialog("Select image file", OpenDialog.getDefaultDirectory(), null);
        String dir = od.getDirectory();
        final String filename = od.getFileName();
        // dialog was canceled
        if (null == dir)
            return;
        if (IJ.isWindows())
            dir = dir.replace('\\', '/');
        if (!dir.endsWith("/"))
            dir += "/";
        // Compare filenames
        if (!filename.equals(f.getName())) {
            YesNoDialog yn = new YesNoDialog(projects.get(patch.getProject()).frame, "WARNING", "Different file names!\n  old: " + f.getName() + "\n  new: " + filename + "\nSet to new file name?");
            if (!yn.yesPressed())
                return;
            // Remove mipmaps: would not be found with the new name and the old ones would remain behind unused
            if (!f.getName().equals(new File(old_path).getName())) {
                // remove mipmaps: the name wouldn't match otherwise
                patch.getProject().getLoader().removeMipMaps(patch);
            }
        }
        // 
        String wrong_parent_path = new File(data.vpath.get(row)).getParent();
        wrong_parent_path = wrong_parent_path.replace('\\', '/');
        // not File.separatorChar, TrakEM2 uses '/' as folder separator
        if (!wrong_parent_path.endsWith("/"))
            wrong_parent_path = new StringBuilder(wrong_parent_path).append('/').toString();
        final String path = new StringBuilder(dir).append(filename).toString();
        // keep track of fixed slices to avoid calling n_slices * n_slices times!
        final HashSet<Patch> fixed = new HashSet<Patch>();
        int n_fixed = 0;
        if (-1 == patch.getFilePath().lastIndexOf("-----#slice=")) {
            if (!fixPatchPath(patch, path, update_mipmaps)) {
                return;
            }
            data.remove(patch);
            fixed.add(patch);
            n_fixed += 1;
        } else {
            int n = fixStack(data, fixed, patch.getStackPatches(), old_path, path, update_mipmaps);
            if (0 == n) {
                // some error ocurred, no paths fixed
                return;
            }
            n_fixed += n;
        // data already cleared of removed patches by fixStack
        }
        String good_parent_path = dir;
        // not File.separatorChar, TrakEM2 uses '/' as folder separator
        if (!dir.endsWith("/"))
            good_parent_path = new StringBuilder(good_parent_path).append('/').toString();
        // Check for similar parent paths and see if they can be fixed
        if (fix_similar) {
            for (int i = data.vp.size() - 1; i > -1; i--) {
                final String wrong_path = data.vpath.get(i);
                final Patch p = data.vp.get(i);
                if (wrong_path.startsWith(wrong_parent_path)) {
                    // try to fix as well
                    final File file = new File(new StringBuilder(good_parent_path).append(wrong_path.substring(wrong_parent_path.length())).toString());
                    if (file.exists()) {
                        if (-1 == p.getFilePath().lastIndexOf("-----#slice=")) {
                            if (!fixed.contains(p) && fixPatchPath(p, file.getAbsolutePath(), update_mipmaps)) {
                                // not by 'i' but by Patch, since if some fail the order is not the same
                                data.remove(p);
                                n_fixed++;
                                fixed.add(p);
                            }
                        } else {
                            if (fixed.contains(p))
                                continue;
                            n_fixed += fixStack(data, fixed, p.getStackPatches(), wrong_path, file.getAbsolutePath(), update_mipmaps);
                        }
                    }
                }
            }
        }
        if (fix_all) {
            // traverse all Patch from the entire project, minus those already fixed
            for (final Displayable d : patch.getLayerSet().getDisplayables(Patch.class)) {
                final Patch p = (Patch) d;
                final String wrong_path = p.getImageFilePath();
                if (wrong_path.startsWith(wrong_parent_path)) {
                    File file = new File(new StringBuilder(good_parent_path).append(wrong_path.substring(wrong_parent_path.length())).toString());
                    if (file.exists()) {
                        if (-1 == p.getFilePath().lastIndexOf("-----#slice=")) {
                            if (!fixed.contains(p) && fixPatchPath(p, file.getAbsolutePath(), update_mipmaps)) {
                                // not by 'i' but by Patch, since if some fail the order is not the same
                                data.remove(p);
                                n_fixed++;
                                fixed.add(p);
                            }
                        } else {
                            if (fixed.contains(p))
                                continue;
                            n_fixed += fixStack(data, fixed, p.getStackPatches(), wrong_path, file.getAbsolutePath(), update_mipmaps);
                        }
                    }
                }
            }
        }
        // if table is empty, close
        if (0 == data.vp.size()) {
            FilePathRepair fpr = projects.remove(patch.getProject());
            fpr.frame.dispose();
        }
        Utils.logAll("Fixed " + n_fixed + " image file path" + (n_fixed > 1 ? "s" : ""));
    }
}
Also used : Displayable(ini.trakem2.display.Displayable) YesNoDialog(ini.trakem2.display.YesNoDialog) Patch(ini.trakem2.display.Patch) File(java.io.File) OpenDialog(ij.io.OpenDialog) HashSet(java.util.HashSet)

Example 65 with Patch

use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.

the class IntegralImageMipMaps method createGRAY8.

@SuppressWarnings({ "unused", "unchecked", "null" })
private static final BufferedImage[] createGRAY8(final Patch patch, final ByteProcessor ip, final ByteProcessor mask) {
    final int w = ip.getWidth();
    final int h = ip.getHeight();
    final int[] dims = new int[] { w, h };
    final ScaleAreaAveraging2d<LongType, UnsignedByteType> saai, saam;
    {
        // Integral of the image
        final IntegralImage<UnsignedByteType, LongType> oa = new IntegralImage<UnsignedByteType, LongType>(wrap((byte[]) ip.getPixels(), dims), new LongType(), new IntegerTypeConverter<UnsignedByteType, LongType>());
        oa.process();
        saai = new ScaleAreaAveraging2d<LongType, UnsignedByteType>(oa.getResult(), new UnsignedByteType(), dims);
        // Integral of the mask, if any
        if (null != mask) {
            final IntegralImage<UnsignedByteType, LongType> ma = new IntegralImage<UnsignedByteType, LongType>(wrap((byte[]) mask.getPixels(), dims), new LongType(), new IntegerTypeConverter<UnsignedByteType, LongType>());
            ma.process();
            saam = new ScaleAreaAveraging2d<LongType, UnsignedByteType>(ma.getResult(), new UnsignedByteType(), dims);
        } else {
            saam = null;
        }
    }
    // Generate images
    final BufferedImage[] bis = new BufferedImage[Loader.getHighestMipMapLevel(patch) + 1];
    // 
    if (null == saam) {
        // mask is null
        // Save images as grayscale
        // sharing the byte[]
        bis[0] = ImageSaver.createGrayImage((byte[]) ip.getPixels(), w, h);
        for (int i = 1; i < bis.length; i++) {
            final int K = (int) Math.pow(2, i), wk = w / K, hk = h / K;
            // An image of the scaled size
            saai.setOutputDimensions(wk, hk);
            saai.process();
            bis[i] = ImageSaver.createGrayImage(((Array<UnsignedByteType, ByteArray>) saai.getResult().getContainer()).update(null).getCurrentStorageArray(), wk, hk);
        }
    } else {
        // Save images as RGBA, where all 3 color channels are the same
        bis[0] = ImageSaver.createARGBImage(blend((byte[]) ip.getPixels(), (byte[]) mask.getPixels()), w, h);
        for (int i = 1; i < bis.length; i++) {
            final int K = (int) Math.pow(2, i), wk = w / K, hk = h / K;
            // An image of the scaled size
            saai.setOutputDimensions(wk, hk);
            saai.process();
            // A mask of the scaled size
            saam.setOutputDimensions(wk, hk);
            saam.process();
            // 
            bis[i] = ImageSaver.createARGBImage(blend(((Array<UnsignedByteType, ByteArray>) saai.getResult().getContainer()).update(null).getCurrentStorageArray(), ((Array<UnsignedByteType, ByteArray>) saam.getResult().getContainer()).update(null).getCurrentStorageArray()), wk, hk);
        }
    }
    return bis;
}
Also used : LongType(mpicbg.imglib.type.numeric.integer.LongType) UnsignedByteType(mpicbg.imglib.type.numeric.integer.UnsignedByteType) BufferedImage(java.awt.image.BufferedImage) ByteArray(mpicbg.imglib.container.basictypecontainer.array.ByteArray) Array(mpicbg.imglib.container.array.Array) FastIntegralImage(ini.trakem2.imaging.FastIntegralImage) IntegralImage(mpicbg.imglib.algorithm.integral.IntegralImage) ScaleAreaAveraging2d(mpicbg.imglib.algorithm.integral.ScaleAreaAveraging2d) ByteArray(mpicbg.imglib.container.basictypecontainer.array.ByteArray) IntegerTypeConverter(mpicbg.imglib.function.IntegerTypeConverter)

Aggregations

Patch (ini.trakem2.display.Patch)69 ArrayList (java.util.ArrayList)46 Layer (ini.trakem2.display.Layer)39 ImagePlus (ij.ImagePlus)34 Rectangle (java.awt.Rectangle)28 Point (mpicbg.models.Point)26 HashSet (java.util.HashSet)24 Displayable (ini.trakem2.display.Displayable)23 AffineTransform (java.awt.geom.AffineTransform)20 Loader (ini.trakem2.persistence.Loader)15 File (java.io.File)15 Future (java.util.concurrent.Future)15 NotEnoughDataPointsException (mpicbg.models.NotEnoughDataPointsException)15 PointMatch (mpicbg.models.PointMatch)14 Worker (ini.trakem2.utils.Worker)13 HashMap (java.util.HashMap)13 ExecutorService (java.util.concurrent.ExecutorService)12 ImageProcessor (ij.process.ImageProcessor)11 AffineModel2D (mpicbg.models.AffineModel2D)11 GenericDialog (ij.gui.GenericDialog)10