Esempio n. 1
0
  /**
   * Save the specified sequence in the specified file.<br>
   * When the sequence contains severals image the multipleFile flag is used to indicate<br>
   * if images are saved as separate files (file then specify a directory) or not.<br>
   * zMin - zMax and tMin - tMax define the Z and T images range to save.<br>
   *
   * @param formatWriter writer used to save sequence (define the image format)
   * @param sequence sequence to save
   * @param filePath file name where we want to save sequence
   * @param zMin start Z position to save
   * @param zMax end Z position to save
   * @param tMin start T position to save
   * @param tMax end T position to save
   * @param fps frame rate for AVI sequence save
   * @param saveFrame progress frame for save operation (can be null)
   * @throws ServiceException
   * @throws IOException
   * @throws FormatException
   */
  private static void save(
      IFormatWriter formatWriter,
      Sequence sequence,
      String filePath,
      int zMin,
      int zMax,
      int tMin,
      int tMax,
      int fps,
      FileFrame saveFrame)
      throws ServiceException, FormatException, IOException {
    final File file = new File(filePath);
    final IFormatWriter writer;

    if (formatWriter == null) writer = getWriter(file, ImageFileFormat.TIFF);
    else writer = formatWriter;

    // TODO: temporary fix for the "incorrect close operation" bug in Bio-Formats
    // with OME TIF writer, remove it when fixed.
    // {
    // try
    // {
    // writer = formatWriter.getClass().newInstance();
    // }
    // catch (Exception e)
    // {
    // throw new ServiceException("Can't create new writer instance: " + e);
    // }
    // }

    if (writer == null)
      throw new UnknownFormatException(
          "Can't find a valid image writer for the specified file: " + filePath);

    // first delete the file else LOCI won't save it correctly
    if (file.exists()) file.delete();
    // ensure parent directory exist
    FileUtil.ensureParentDirExist(file);

    final int sizeC = sequence.getSizeC();
    final boolean separateChannel = getSeparateChannelFlag(writer, sequence.getColorModel());

    // set settings
    writer.setFramesPerSecond(fps);
    // generate metadata
    writer.setMetadataRetrieve(
        MetaDataUtil.generateMetaData(
            sequence, (zMax - zMin) + 1, (tMax - tMin) + 1, separateChannel));
    // no interleave (XP default viewer want interleaved channel to correctly read image)
    writer.setInterleaved(false);
    // set id
    writer.setId(filePath);
    // init
    writer.setSeries(0);
    // usually give better save performance
    writer.setWriteSequentially(true);

    // get endianess
    final boolean littleEndian =
        !writer.getMetadataRetrieve().getPixelsBinDataBigEndian(0, 0).booleanValue();
    byte[] data = null;

    try {
      int imageIndex = 0;
      // XYCZT order is important here (see metadata)
      for (int t = tMin; t <= tMax; t++) {
        for (int z = zMin; z <= zMax; z++) {
          if ((saveFrame != null) && saveFrame.isCancelRequested()) return;

          final IcyBufferedImage image = sequence.getImage(t, z);

          // separated channel data
          if (separateChannel) {
            for (int c = 0; c < sizeC; c++) {
              if (image != null) {
                // avoid multiple allocation
                data = image.getRawData(c, data, 0, littleEndian);
                writer.saveBytes(imageIndex, data);
              }

              imageIndex++;
            }
          } else {
            if (image != null) {
              // avoid multiple allocation
              data = image.getRawData(data, 0, littleEndian);
              writer.saveBytes(imageIndex, data);
            }

            imageIndex++;
          }

          if (saveFrame != null) saveFrame.incPosition();
        }
      }
    } finally {
      // always close writer after a file has been saved
      writer.close();
    }
  }
Esempio n. 2
0
  /** Save a single image from bytes buffer to the specified file. */
  private static void saveImage(
      IFormatWriter formatWriter,
      byte[] data,
      int width,
      int height,
      int numChannel,
      boolean separateChannel,
      DataType dataType,
      File file,
      boolean force)
      throws FormatException, IOException {
    final String filePath = FileUtil.cleanPath(FileUtil.getGenericPath(file.getAbsolutePath()));

    if (FileUtil.exists(filePath)) {
      // forced ? first delete the file else LOCI won't save it
      if (force) FileUtil.delete(filePath, true);
      else throw new IOException("File already exists");
    }
    // ensure parent directory exist
    FileUtil.ensureParentDirExist(filePath);

    final IFormatWriter writer;
    final boolean separateCh;

    if (formatWriter == null) {
      // get the writer
      writer = getWriter(FileUtil.getFileExtension(filePath, false), ImageFileFormat.TIFF);

      // prepare the metadata
      try {
        separateCh = getSeparateChannelFlag(writer, numChannel, dataType);
        writer.setMetadataRetrieve(
            MetaDataUtil.generateMetaData(width, height, numChannel, dataType, separateCh));
      } catch (ServiceException e) {
        System.err.println("Saver.saveImage(...) error :");
        IcyExceptionHandler.showErrorMessage(e, true);
      }
    } else {
      // ready to use writer (metadata already prepared)
      writer = formatWriter;
      separateCh = separateChannel;
    }

    // we never interleaved data even if some image viewer need it to correctly read image (win XP
    // viewer)
    writer.setInterleaved(false);
    writer.setId(filePath);
    writer.setSeries(0);
    // usually give better save performance
    writer.setWriteSequentially(true);

    try {
      // separated channel data
      if (separateChannel) {
        final int pitch = width * height * dataType.getSize();
        final byte[] dataChannel = new byte[pitch];
        int offset = 0;

        for (int c = 0; c < numChannel; c++) {
          System.arraycopy(data, offset, dataChannel, 0, pitch);
          writer.saveBytes(c, dataChannel);
          offset += pitch;
        }
      } else
        // save all data at once
        writer.saveBytes(0, data);
    } catch (Exception e) {
      System.err.println("Saver.saveImage(...) error :");
      IcyExceptionHandler.showErrorMessage(e, true);
    }

    writer.close();
  }