[INJICERT-1226] Add image-compressor utility for mosipid plugin#132
[INJICERT-1226] Add image-compressor utility for mosipid plugin#132swatigoel merged 4 commits intoinji:developfrom
Conversation
Signed-off-by: Piyush7034 <piyushshukla2100@gmail.com>
WalkthroughAdds image-compression support: new Maven dependencies, an ImageCompression service and utility, OpenCV native loading, and integration into the data provider to post-process JWT "picture" claims into an added compressed image field. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Ida as IdaDataProviderPluginImpl
participant Util as ImageCompressorUtil
participant Service as ImageCompressorServiceImpl
participant OpenCV as OpenCV_Native_Library
Client->>Ida: fetchData(token)
Ida->>Ida: parse JWT claims
alt picture present
Ida->>Util: extractAndCompressImage(dataURI)
Util->>Util: validate & parse data URI
Util->>Util: base64 decode -> image bytes
loop attempts (up to configured max)
Util->>Service: doResizeAndCompress(imageBytes)
Service->>OpenCV: native resize/compress
OpenCV-->>Service: compressed bytes (JP2)
Service-->>Util: compressed bytes
Util->>Util: check size threshold
end
Util->>Util: convert JP2 -> PNG/JPEG, base64 encode -> dataURI
Util-->>Ida: compressed dataURI
Ida->>Ida: add "picture" and "compressedPicture" to JSON
end
Ida-->>Client: return JSON claims
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In
`@mosip-identity-certify-plugin/src/main/java/io/mosip/certify/mosipid/integration/helper/ImageCompressorUtil.java`:
- Around line 100-108: The catch-all in ImageCompressorUtil is currently
catching and re-wrapping DataProviderExchangeException thrown earlier (e.g.,
when max attempts exceeded), losing the original code and message; fix this by
adding a specific catch for DataProviderExchangeException (or checking
instanceof in the generic catch) before the catch(Exception e) to rethrow the
original DataProviderExchangeException unchanged (preserve its error code and
message), and keep the existing IllegalArgumentException and general Exception
handlers (which should still log via log.error and wrap other exceptions into
ERROR_COMPRESSING_IMAGE).
In
`@mosip-identity-certify-plugin/src/main/java/io/mosip/certify/mosipid/integration/service/IdaDataProviderPluginImpl.java`:
- Around line 47-61: The static initializer sets the OPENCV IO flag via
System.setProperty("OPENCV_IO_ENABLE_JASPER","1") but logs
System.getenv("OPENCV_IO_ENABLE_JASPER"), causing a mismatch; change the logging
to read the same source you set (System.getProperty) or set the environment
before class load so both match, and avoid using log.info in the static block by
either switching to System.out.println for this static init message or moving
the logging to a `@PostConstruct` (or initialization method) where the logging
framework is guaranteed initialized; update references to
System.setProperty/System.getProperty and replace log.info(...) in the static
block accordingly.
🧹 Nitpick comments (1)
mosip-identity-certify-plugin/src/main/java/io/mosip/certify/mosipid/integration/helper/ImageCompressorUtil.java (1)
61-83: Recompression strategy may not be effective and could degrade quality.Recompressing an already-compressed JP2 image (line 82:
inputBytes = jp2Bytes) is unlikely to achieve significant size reduction since the compression is already applied. Each recompression iteration may degrade image quality without proportional size benefits.Consider alternative approaches:
- Adjusting compression quality parameters on the initial pass
- Resizing/downscaling the image dimensions before compression
Additionally, the
targetSizeconstant (4096 bytes) is hardcoded. Consider making it configurable via application properties for flexibility.
...fy-plugin/src/main/java/io/mosip/certify/mosipid/integration/helper/ImageCompressorUtil.java
Show resolved
Hide resolved
...in/src/main/java/io/mosip/certify/mosipid/integration/service/IdaDataProviderPluginImpl.java
Show resolved
Hide resolved
Signed-off-by: Piyush7034 <piyushshukla2100@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@mosip-identity-certify-plugin/src/main/java/io/mosip/certify/mosipid/integration/helper/ImageCompressorUtil.java`:
- Around line 76-78: The size check currently validates jp2Bytes against
maxAllowedImageSize before converting to the final image format; change the
logic to perform the size validation after format conversion using the final
output byte array (e.g., finalBytes) so the constraint applies to the actual
PNG/JPEG produced. Locate the block that produces jp2Bytes and the subsequent
conversion branches (the code that writes/creates PNG or JPEG from jp2Bytes) and
move or add the check to compare finalBytes.length to maxAllowedImageSize;
ensure both conversion paths (PNG and JPEG) perform this post-conversion check
and handle the oversized case the same way the original check did.
♻️ Duplicate comments (1)
mosip-identity-certify-plugin/src/main/java/io/mosip/certify/mosipid/integration/helper/ImageCompressorUtil.java (1)
105-114: Exception handling swallowsDataProviderExchangeExceptionthrown from compression loop.The
DataProviderExchangeExceptionthrown at lines 80-83 (with codeFACE_IMAGE_TOO_LARGE) will be caught by the genericcatch (Exception e)and re-wrapped withERROR_COMPRESSING_IMAGE, losing the original error code.🐛 Proposed fix to preserve DataProviderExchangeException
} catch (IllegalArgumentException iae) { log.error("ERROR_PARSING_IMAGE_DATA", iae); throw new DataProviderExchangeException("ERROR_PARSING_IMAGE_DATA", iae.getMessage()); + } catch (DataProviderExchangeException dpe) { + throw dpe; } catch (Exception e) { log.error("Image compression failed", e); throw new DataProviderExchangeException( "ERROR_COMPRESSING_IMAGE", "Failed to compress image data. Check the image format and other properties." ); }
...fy-plugin/src/main/java/io/mosip/certify/mosipid/integration/helper/ImageCompressorUtil.java
Show resolved
Hide resolved
Signed-off-by: Piyush7034 <piyushshukla2100@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
mosip-identity-certify-plugin/src/main/java/io/mosip/certify/mosipid/integration/service/IdaDataProviderPluginImpl.java (1)
130-148: Preserve DataProviderExchangeException from image compression.
extractAndCompressImagethrowsDataProviderExchangeException, but the catch-all wraps it intoERROR_FETCHING_KYC_DATA, losing the original error code/message. Add a specific catch to rethrow.🔧 Proposed fix
- catch (JSONException | JsonProcessingException e) { + catch (JSONException | JsonProcessingException e) { log.error("Error occurred during json processing: " + e.getMessage()); throw new DataProviderExchangeException("JSON_PARSING_FAILED", e.getMessage()); } + catch (DataProviderExchangeException e) { + throw e; + } catch (Exception e) { log.error("ERROR_FETCHING_KYC_DATA. " + e.getMessage()); throw new DataProviderExchangeException("ERROR_FETCHING_KYC_DATA", e.getMessage()); }
♻️ Duplicate comments (1)
mosip-identity-certify-plugin/src/main/java/io/mosip/certify/mosipid/integration/helper/ImageCompressorUtil.java (1)
72-103: Validate max size after JP2→PNG/JPEG conversion.The limit is enforced on JP2 bytes, but the final PNG/JPEG can be larger, so the constraint may be violated. Please move the size check to apply to the final output bytes.
🔧 Proposed fix
- if (jp2Bytes.length <= maxAllowedImageSize) { - break; - } - if (attempts >= maxRetryAttempts) { - throw new DataProviderExchangeException( - "FACE_IMAGE_TOO_LARGE", - "Unable to compress image with available compression. Check size or quality of the input image." - ); - } - - // use the last compressed output as the next input - inputBytes = jp2Bytes; - } - - // Convert JP2 → desired output format - final byte[] outBytes; - final String outMime; - if (usePng) { - outBytes = CommonUtil.convertJP2ToPNGBytes(jp2Bytes); - outMime = "image/png"; - } else { - outBytes = CommonUtil.convertJP2ToJPEGBytes(jp2Bytes); - outMime = "image/jpeg"; - } - - // Encode and return as Data URI - final String b64 = Base64.getEncoder().encodeToString(outBytes); - return "data:" + outMime + ";base64," + b64; + // Convert JP2 → desired output format + final byte[] outBytes; + final String outMime; + if (usePng) { + outBytes = CommonUtil.convertJP2ToPNGBytes(jp2Bytes); + outMime = "image/png"; + } else { + outBytes = CommonUtil.convertJP2ToJPEGBytes(jp2Bytes); + outMime = "image/jpeg"; + } + + if (outBytes.length <= maxAllowedImageSize) { + // Encode and return as Data URI + final String b64 = Base64.getEncoder().encodeToString(outBytes); + return "data:" + outMime + ";base64," + b64; + } + if (attempts >= maxRetryAttempts) { + throw new DataProviderExchangeException( + "FACE_IMAGE_TOO_LARGE", + "Unable to compress image with available compression. Check size or quality of the input image." + ); + } + + // use the last compressed output as the next input + inputBytes = jp2Bytes; + }
Signed-off-by: Piyush7034 <piyushshukla2100@gmail.com>
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.