GroupDocs.Signature for Java 23.12 Release Notes
In this release, we are excited to announce support of the multi-layers DICOM files support. New product features allow to process and manage DICOM documents with new signatures, obtain file information, and provide searching for signature artifacts. This development will enhance the usability of our product in a variety of healthcare, and medical imaging applications. There are about 9 features, 3 enhancements and 13 bug fixes in this release.
Full list of changes in this release
Key | Category | Summary |
---|---|---|
SIGNATURENET-4530 | ★ Feature | Implement searching for signatures within the Archives |
SIGNATURENET-4559 | ★ Feature | Implement searching DICOM image documents for signatures |
SIGNATURENET-4557 | ★ Feature | Implement obtaining DICOM image documents information |
SIGNATURENET-4501 | ★ Feature | Implement signing DICOM image documents |
SIGNATURENET-4372 | ★ Feature | Implement Searching in the Certificate documents |
SIGNATURENET-4605 | ★ Feature | Implement verification DICOM image documents for signatures |
SIGNATURENET-4574 | ★ Feature | Implement preview for DICOM image documents |
SIGNATURENET-4595 | ★ Feature | Respect saving XmpData package for DICOM |
SIGNATURENET-4598 | ★ Feature | Implement gathering extended DICOM XmpData into the DocumentInfo |
SIGNATURENET-4537 | ★ Enhancement | Extend DocumentResultSignature with the Error message |
SIGNATURENET-4532 | ★ Enhancement | Provide signing Spreadsheets by using digital signature as container for certificates |
SIGNATURENET-4602 | ★ Enhancement | Provide size and position for image search result Barcode and QrCode signatures |
SIGNATURENET-4533 | 🔧 Fix | The output signed archive contains trial limitations |
SIGNATURENET-4531 | 🔧 Fix | Unexpected border line appearance of Stamp signature when corners set at too big values |
SIGNATURENET-4510 | 🔧 Fix | Line background overlaps border of Stamp signature result |
SIGNATURENET-4509 | 🔧 Fix | The different border widths of the Stamp Signature appearance |
SIGNATURENET-4508 | 🔧 Fix | Unexpected visual artifacts for Stamp signature appearance |
SIGNATURENET-4487 | 🔧 Fix | Word processing documents are not signed within the archive files |
SIGNATURENET-4548 | 🔧 Fix | Digital certificate issue with signing under Linux |
SIGNATURENET-4505 | 🔧 Fix | Some two-pages WordProcessing documents could not be signed at trial mode |
SIGNATURENET-4486 | 🔧 Fix | Digital certificate for Spreadsheets has wrong format |
SIGNATURENET-4481 | 🔧 Fix | Aspose.Word 23.1 Digitally signed .ODT document raises exception during digital signatures deletion |
SIGNATURENET-4432 | 🔧 Fix | Digitally signed Open Office .ODT document raises exception during digital signatures deletion |
SIGNATURENET-4599 | 🔧 Fix | Search processing does not give expected results due to evaluation message in internal output images |
SIGNATURENET-4504 | 🔧 Fix | Wrong signature position for documents signed in archives |
Major Features
This release includes four new archive features and one enhancement:
- Implement searching for signatures within the Archives
- Implement searching DICOM image documents for signatures
- Implement obtaining DICOM image documents information
- Implement signing DICOM image documents
- Implement Searching in the Certificate documents
- Extend DocumentResultSignature with the Error message
- Implement verification DICOM image documents for signatures
- Implement preview for DICOM image documents
- Respect saving XmpData package for DICOM
- Implement gathering extended DICOM XmpData into the DocumentInfo
Implement searching for signatures within the Archives
🌐 The existing class DocumentResultSignature will keep Search sigantures for the result of the particular processed document.
/// <summary>
/// Implement searching for signatures within the Archives
/// </summary>
Signature signature = new Signature(filePath);
{
// create list of signature options
BarcodeSearchOptions bcOptions = new BarcodeSearchOptions(BarcodeTypes.Code128);
QrCodeSearchOptions qrOptions = new QrCodeSearchOptions(QrCodeTypes.QR);
// setup search options
List<SearchOptions> listOptions = new ArrayList<SearchOptions>();
listOptions.add(bcOptions);
listOptions.add(qrOptions);
// search archive for documents
SearchResult searchResult = signature.search(listOptions);
// check the result
System.out.print("\nList of successfully processed documents:");
int number = 1;
for (BaseSignature o : searchResult.getSucceeded())
{
DocumentResultSignature document = (DocumentResultSignature)o;
System.out.print("Document #"+number++ +": "+document.getFileName()+". Processed: "+document.getProcessingTime()+", mls");
for (BaseSignature temp : document.getSucceeded())
{
System.out.print("\t\t#"+temp.getSignatureId()+": "+temp.getSignatureType());
}
}
if (searchResult.getFailed().size() > 0)
{
System.out.print("\nList of failed documents:");
number = 1;
for (BaseSignature o : searchResult.getFailed())
{
DocumentResultSignature document = (DocumentResultSignature)o;
System.out.print("ERROR in Document #"+number++ +"-"+document.getFileName()+": "+document.getErrorMessage()+", mls");
}
}
}
Implement searching DICOM image documents for signatures
🌐 The searching process within the DICOM documents does not look different than searching for single-page raster image, except for the fact that all result images will contain the page number of the layer where the signature was found.
/// <summary>
/// Search multi-layer image document for signatures.
/// This example provided for formats like DICOM
/// </summary>
Signature signature = new Signature("signed.dcm");
{
// setup search options
QrCodeSearchOptions searchOptions = new QrCodeSearchOptions();
{
// enable grabbing image content feature
searchOptions.setReturnContent(true);
// specify exact image type to be returned
searchOptions.setReturnContentType(FileType.PNG);
};
// search multi-layer document
List<QrCodeSignature> signatures = signature.search(QrCodeSignature.class, searchOptions);
System.out.print("\nSource document ['"+fileName+"'] contains following QR-code signature(s).");
// output signatures
for (QrCodeSignature qrSignature : signatures)
{
// due to multi-layers each signature will contain the page number
System.out.print("Found Qr-Code "+qrSignature.getText()+" signature at page "+qrSignature.getPageNumber()+" and id# "+qrSignature.getSignatureId()+".");
System.out.print("Location at "+qrSignature.getLeft()+"-"+qrSignature.getTop()+". Size is "+qrSignature.getWidth()+"x"+qrSignature.getHeight()+".");
}
}
Implement obtaining DICOM image documents information
🌐 How to obtain the DICOM image information - this is a functionality that provides users with easy access to vital details embedded within the DICOM files. This includes each image page information and its size.
/// <summary>
/// Obtain information from multi-layer image document.
/// This example provided for formats like DICOM
/// </summary>
Signature signature = new Signature(filePath);
{
IDocumentInfo documentInfo = signature.getDocumentInfo();
System.out.print("Document properties "+ filePath);
System.out.print(" - format : "+documentInfo.getFileType().getFileFormat());
System.out.print(" - extension : "+documentInfo.getFileType().getExtension());
System.out.print(" - size : "+documentInfo.getSize());
System.out.print(" - page count : "+documentInfo.getPageCount());
for (PageInfo pageInfo : documentInfo.getPages())
{
System.out.print(" - page-"+pageInfo.getPageNumber()+" Width "+pageInfo.getWidth()+", Height "+pageInfo.getHeight());
}
}
Implement signing DICOM image documents
🌐 Public API to sign the multilayer image documents is the same as signing any other file format. The output SignResult instance will contains the newly added signature objects with the PageNumber equal to image layer index + 1. So the setPageNumber property for the multilayer images will keep values from 1 (not 0-based).
/// <summary>
/// Sign multi-layer image document.
/// </summary>
Signature signature = new Signature("sample.dcm");
{
QrCodeSignOptions options = new QrCodeSignOptions("Patient #36363393. R: No-Issues");
{
Padding padding = new Padding();
// set signature position
padding.setRight(5);
padding.setLeft(5);
options.setMargin(tmp0);
// set signature rectangle
options.setWidth(100);
options.setHeight(100);
};
// sign document to file
SignResult signResult = signature.sign(outputFilePath, options);
System.out.print("\nSource document signed successfully with "+signResult.getSucceeded().size()+" signature(s).\nFile saved at "+outputFilePath);
System.out.print("\nList of newly created signatures:");
for (BaseSignature temp : signResult.getSucceeded())
{
System.out.print(temp.getSignatureType()+" at page #"+temp.getPageNumber()+": Id:"+temp.getSignatureId()+".");
}
}
Implement Searching in the Certificate documents
🌐 In this release, we’ve introduced new search options CertificateSearchOptions to provide search capabilities for certificates. Now, users can quickly locate critical information within their certificates by searching for particular data. Example below demonstrates how to search if certificate contain specific string from the serial number.
/// <summary>
/// Search if certificate contain specific string from the serial number.
/// </summary>
Signature signature = new Signature(certificatePath, loadOptions);
{
CertificateSearchOptions options = new CertificateSearchOptions();
{
// check the serial number
options.setText("AAD0D15C628A");
// find exact math
options.setMatchType(TextMatchType.Contains);
};
// search for certificate data
List<MetadataSignature> result = signature.search(MetadataSignature.class, options);
if (result.size()>0)
{
System.out.print("\nCertificate contains following search results");
for (MetadataSignature temp : result)
{
System.out.print("\t\t-"+temp.getName()+" - "+temp.getValue());
}
}
else
{
System.out.print("\nCertificate failed search process.");
}
}
Extend DocumentResultSignature with the Error message
🌐 For the archive document processing, when the SignResult contains list of succeeded and failed DocumentResultSignature elements we added new property to monitor the error. Following example shows how to analyze this variable.
/// <summary>
/// Support Succeeded and Failed list as result of processing archives
/// </summary>
Signature signature = new Signature("sample.zip");
{
// create sign options
TextSignOptions options = new TextSignOptions("signed!")
{
// set signature position
options.setLeft(100);
options.setTop(100);
};
// sign archive to new zip file
SignResult result = signature.sign("output.zip", options);
// analyze the failed documents
for (BaseSignature o : result.getFailed())
{
DocumentResultSignature document = (DocumentResultSignature)o;
System.out.print("ERROR in Document #"+number++ +"-"+document.getFileName()+": "+document.getErrorMessage());
}
}
Implement verification DICOM image documents for signatures
🌐 The verification process within the DICOM documents does not look different than verification for single-page raster image, except for the fact that all result images will contain the page number of the layer where the signature was verified.
/// <summary>
/// Verify multi-layer image document for signatures.
/// This example provided for formats like DICOM
/// </summary>
Signature signature = new Signature("signed.dcm");
{
QrCodeVerifyOptions options = new QrCodeVerifyOptions();
{
options.setAllPages(true);
options.setText("Patient #36363393");
options.setMatchType(TextMatchType.Contains);
};
VerificationResult result = signature.verify(options);
if (result.isValid())
{
System.out.print("\nDICOM "+filePath+" has "+result.getSucceeded().size()+" successfully verified signatures!");
}
else
{
System.out.print("\nDocument "+filePath+" failed verification process.");
}
}
Implement preview for DICOM image documents
🌐 How to preview the DICOM image information
/// <summary>
/// Generate preview for DICOM document
/// </summary>
Signature signature = new Signature("signed.dcm"))
{
PreviewOptions previewOption = new PreviewOptions(new PageStreamFactory() {
@Override
public OutputStream createPageStream(int pageNumber) {
return generatePageStream(pageNumber);
}
@Override
public void closePageStream(int pageNumber, OutputStream pageStream) {
releasePageStream(pageNumber, pageStream);
}
});
signature.generatePreview(previewOption);
System.out.print("\nDICOM ['"+filePath+"'] pages previews were successfully generated!");
}
private static OutputStream generatePageStream(int pageNumber)
{
try {
String filePath = Constants.OutputPath +"\\SignDicomImageAdvanced\\image-"+pageNumber+".jpg";
return new FileOutputStream(filePath);
}catch (Exception e){
throw new RuntimeException(e.getMessage());
}
}
private static void releasePageStream(int pageNumber, OutputStream pageStream)
{
try {
pageStream.close();
String imageFilePath = new File(Constants.OutputPath + "\\SignDicomImageAdvanced", "image-" +pageNumber + ".jpg").getPath();
System.out.print("Image file "+imageFilePath+" is ready for preview");
}catch (Exception e){
System.out.print(e.getMessage());
}
}
Respect saving XmpData package for DICOM
🌐 In this release, we’ve introduced extended DICOM XmpData DicomXmpType to provide ability to get and update DICOM metadata. It may be done using DicomSaveOptions
/// <summary>
/// Sign multi-layer image document and add xmp metadata
/// </summary>
Signature signature = new Signature("sample.dcm"))
{
QrCodeSignOptions options = new QrCodeSignOptions("Patient #36363393. R: No-Issues");
{
// set QR area
options.setWidth(100);
options.setHeight(100);
// put right bottom corner
options.setVerticalAlignment(VerticalAlignment.Bottom);
options.setHorizontalAlignment(HorizontalAlignment.Right);
Padding padding = new Padding();
padding.setRight(5);
padding.setLeft(5);
options.setMargin(padding);
};
DicomSaveOptions dicomSaveOptions = new DicomSaveOptions()
List<DicomXmpEntry> list = new ArrayList<DicomXmpEntry>();
list.add(new DicomXmpEntry(DicomXmpType.PatientName, "Patient #4"));
dicomSaveOptions.setXmpEntries(list);
SignResult signResult = signature.sign(outputFilePath, options, dicomSaveOptions);
}
Implement gathering extended DICOM XmpData into the DocumentInfo
/// <summary>
/// Gathering extended DICOM XmpData into the DocumentInfo
/// </summary>
Signature signature = new Signature("sample.dcm");
{
System.out.print("\nList of DICOM xmp metadata:");
IDocumentInfo signedDocumentInfo = signature.getDocumentInfo();
for (MetadataSignature item : signedDocumentInfo.getMetadataSignatures())
{
System.out.print(item.toString());
}
}