Troubleshooting Common Sanselan Errors and Fixes

Troubleshooting Common Sanselan Errors and Fixes

Sanselan (now Apache Commons Imaging) is a Java library for reading and writing image formats. Below are common errors you may encounter when using Sanselan and concise, actionable fixes.

1. NoClassDefFoundError or ClassNotFoundException for Sanselan classes

  • Cause: Library JAR not on classpath or missing Maven/Gradle dependency.
  • Fix:
    1. If using Maven, add:

      xml

      <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-imaging</artifactId> <version>1.0-alpha2</version> </dependency>

      (adjust version to the latest stable release).

    2. If using Gradle:

      groovy

      implementation ‘org.apache.commons:commons-imaging:1.0-alpha2’
    3. For manual setups, ensure the commons-imaging JAR is included in your runtime classpath.

2. UnsupportedImageFormatException or “Image format not recognized”

  • Cause: Input file is corrupted, uses an uncommon/unsupported codec, or its file signature doesn’t match the extension.
  • Fix:
    1. Verify file integrity by opening it with an image viewer.
    2. Use Sanselan’s format detection:

      java

      ImageFormat format = Imaging.guessFormat(file);

      and log the result.

    3. If format is unsupported, convert the image with an external tool (ImageMagick) to a supported format (PNG/JPEG/TIFF) before processing.
    4. For mismatched extensions, rely on format detection rather than file extension.

3. IIOException / EOFException during read

  • Cause: Truncated stream, partial download, or incorrect stream handling.
  • Fix:
    1. Ensure InputStream supports full read; avoid reusing streams without resetting.
    2. If reading from network, download to a temporary file first and validate size.
    3. Wrap streams properly:

      java

      try (InputStream is = new BufferedInputStream(new FileInputStream(file))) { BufferedImage img = Imaging.getBufferedImage(is); }

4. Incorrect image orientation or missing EXIF rotation

  • Cause: EXIF orientation not applied when rendering.
  • Fix:
    1. Read EXIF metadata and apply rotation:

      java

      Map<String, Object> params = new HashMap<>(); ImageMetadata metadata = Imaging.getMetadata(file); TiffImageMetadata exif = (TiffImageMetadata) Imaging.getMetadata(file); // Read orientation tag and rotate BufferedImage accordingly
    2. Use utility logic to rotate/flip the BufferedImage based on orientation values (1–8).

5. Metadata read/write issues (missing or malformed EXIF)

  • Cause: Wrong metadata APIs used or improper parameter settings when writing.
  • Fix:
    1. To read EXIF, use:

      java

      JpegImageMetadata jpegMetadata = (JpegImageMetadata) Imaging.getMetadata(file); TiffField field = jpegMetadata.findEXIFValueWithExactMatch(TiffTagConstants.TIFF_TAGMAKE);
    2. To write EXIF, construct TiffOutputSet and write using Imaging.writeImage with proper params. Preserve existing EXIF by reading TiffOutputSet from existing metadata and modifying it before writing.
    3. Validate tags against TIFF/EXIF spec and use known tag constants from the library.

6. Slow performance when processing many images

  • Cause: Repeated initialization, synchronous I/O, or large images consuming memory.
  • Fix:
    1. Reuse parsers where possible and avoid repeated library initialization.
    2. Process images in parallel using a bounded thread pool:

      java

      ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
    3. Stream to disk for very large images or downscale images using Image#getScaledInstance before heavy processing.
    4. Use BufferedInputStream to reduce I/O overhead.

7. PermissionDenied / FileNotFoundException when writing files

  • Cause: Insufficient filesystem permissions or invalid output path.
  • Fix:
    1. Verify the application has write permissions to the target directory.
    2. Ensure parent directories exist or create them before writing:

      java

      file.getParentFile().mkdirs();
    3. Use try-with-resources to close streams and free locks.

8

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *