GroupDocs.Annotation for Java 21.7 Release Notes

Major Features

In this version Below the list of most notable changes in release of GroupDocs.Annotation for Java 21.7:

  • Legacy API was removed from product
  • Fixed several bugs and issues
  • Added new type of annotation - Image Annotation for (SpreadSheet, Diagrams, Images, PDF, WordProcessing, Presentations)
  • Investigated and fixed coordinates of annotations to make them same on images preview as on documents for number of formats (PDF, Cells, Slides, Words)
  • Adding showing distance value for Distance annotations in different formats (Slides, PDF, Images, Diagrams, Cells)
  • Fixed Background color for highlight annotation is not set in Images
  • Implemented ability to add Image Annotations to Diagrams
  • Added overloads for Remove method
  • Implement image extracting of ImageAnnotation
  • Fixed support DWG files
  • Fixed issue with encrypted SpreadSheet(Cells) files
  • Added new feature for managing different versions of annotated documents (supported formats: Words, PDF, PowerPoint and Open Document format presentations, Excel and Open Document format spreadsheets)
  • Added advanced rendering options for show\hide replies
  • Added to new API getting pages image size
  • Fixed issue with throwing exception for encrypted Excel spreadsheets
  • Fixed cleanup replies for PowerPoint presentations
  • Annotation available in document after removing
  • Issue with generating preview for password-protected document
  • Issue with error when processing images
  • Implemented managing different versions of annotated documents for Images and Diagrams
  • Implemented additional overloads for Save method without filestream
  • Fixed background opacity for PNG files
  • Fixed issue with PagesInfo for Excel files in MVC project
  • Fixed clearing comments for Excel files
  • Fixed unable to Save document as file that was used to create annotator
  • Implemented Angle property for Image Annotation
  • Implemented horizontal and vertical alignment for Watermark
  • Implemented text horizontal alignment for TextField
  • Fixed saving only specific annotation types for html, email, words and image
  • Improved exceptions usage
  • Fixed incorrect position of text annotations types in Cells
  • Improved adding annotations to TIFF Images
  • Improved annotating images mechanism (optimized performance)
  • Added Equals operator for comparing Annotations
  • Fixed issue with open CAD files
  • Fixed failed to import annotations that was added on older versions (added backward compatibility)
  • Fixed issue with ImageData is not saving on Image annotation
  • Fixed restoring image from ImageData
  • Improved adding ImageAnnotation functionality
  • Fixed exception while processing specific xlsx files
  • Fixed exception while annotating email files
  • Fixed issue with streams when Save method invoked
  • Fixed Replacement annotation on Words files
  • Improve annotating PDF functionality by separating PdfCommentator to smaller classes and refactoring it
  • Fixed Index was out of range exception for specific Diagrams
  • Fixed issues with opening big Spreadsheet documents
  • Fixed issues with saving document as an image
  • Fixed Object reference not set to an instance of an object for specific CAD files
  • Implemented generating of specified worksheet columns for the Cells format
  • Improved Cells generating preview by splitting the worksheet into multiple images
  • Fixed Empty PagesInfo in specific diagram file

Full List of Issues Covering all Changes in this Release

KeySummaryIssue Type
ANNOTATIONNET-1421Implement horizontal text alignment TextField and TextWatermark annotationsFeature
ANNOTATIONNET-1292Implement managing different versions of annotated documents for DiagramsFeature
ANNOTATIONNET-1291Implement managing different versions of annotated documents for ImagesFeature
ANNOTATIONNET-884Implement ability to add Image annotation to DiagramsFeature
ANNOTATIONNET-880Implement ability to add Image annotation to PDFFeature
ANNOTATIONNET-881Implement ability to add Image annotation to SpreadSheetFeature
ANNOTATIONNET-882Implement ability to add Image annotation to PresentationsFeature
ANNOTATIONNET-883Implement ability to add Image annotation to WordProcessingFeature
ANNOTATIONNET-1220Implement ability to add Image annotation to ImagesFeature
ANNOTATIONNET-816Managing different versions of annotated fileFeature
ANNOTATIONNET-1537Investigate the way of displaying huge worksheets of SpreadsheetImprovement
ANNOTATIONNET-1482Replace file ImageAnnotation functionality with streamsImprovement
ANNOTATIONNET-1418Improve adding annotations to TIFF ImagesImprovement
ANNOTATIONNET-1450Improve ImageAnnotationHelperImprovement
ANNOTATIONNET-1452Add comparison operator (Equals) overload for Annotation ModelsImprovement
ANNOTATIONNET-1427Improve CellsInfo method in DocumentInfoExtractorImprovement
ANNOTATIONNET-1355Improve exceptions usage.Improvement
ANNOTATIONNET-1396Improve PDF document annotation accuracyImprovement
ANNOTATIONNET-1369Add overloads for Annotator.Save method without stream or filepathImprovement
ANNOTATIONNET-1320Pages image sizeImprovement
ANNOTATIONNET-1318Document advanced rendering modes and options supportImprovement
ANNOTATIONNET-1241Add overloads for Annotator Remove MethodImprovement
ANNOTATIONNET-1248Implement image extracting to ImageAnnotationImprovement
ANNOTATIONNET-1135Investigate and fix coordinates discrepancy for CellsImprovement
ANNOTATIONNET-1139Investigate and fix coordinates discrepancy for PDFImprovement
ANNOTATIONNET-1140Investigate and fix coordinates discrepancy for SlidesImprovement
ANNOTATIONNET-1141Investigate and fix coordinates discrepancy for WordsImprovement
ANNOTATIONNET-1146Improve Words Shapes ImportImprovement
ANNOTATIONNET-1165Adding showing distance value for Distance annotations in different formats(Slides, PDF, Images, Diagrams, Cells)Improvement
ANNOTATIONNET-1170Improve Logging in CellsImprovement
ANNOTATIONNET-1171Improve Logging in DiagramImprovement
ANNOTATIONNET-1172Improve Logging in Email/HtmlImprovement
ANNOTATIONNET-1173Improve Logging in ImagesImprovement
ANNOTATIONNET-1174Improve Logging in PDFImprovement
ANNOTATIONNET-1175Improve Logging in SlidesImprovement
ANNOTATIONNET-1176Improve Logging in WordsImprovement
ANNOTATIONNET-1177Improve Logging in Common ClassesImprovement
ANNOTATIONNET-1484Split PdfCommentator functionality to improve annotating PDFImprovement
ANNOTATIONNET-1514Incorrect image size for Excel documentBug
ANNOTATIONNET-1540PagesInfo is emptyBug
ANNOTATIONNET-1536Index was out of range. Must be non-negative and less than the size of the collection for Diagrams documentBug
ANNOTATIONNET-1516Image saving failedBug
ANNOTATIONNET-1515Object reference not set to an instance of an object for CAD file.Bug
ANNOTATIONNET-1513Index out of range on specific Diagrams documentBug
ANNOTATIONNET-1490Cannot open Cells fileBug
ANNOTATIONNET-1392Replacement annotation damages words fileBug
ANNOTATIONNET-1485CorruptedOrDamagedFileException on opening xlsx filesBug
ANNOTATIONNET-1486Method Annotator.Save returns closed streamBug
ANNOTATIONNET-1487Can’t get document info for msg fileBug
ANNOTATIONNET-1488NullReferenceException when annotating e-mailBug
ANNOTATIONNET-1457Cad file can’t be openedBug
ANNOTATIONNET-1458Failed to import annotations that was added on older versionsBug
ANNOTATIONNET-1460ImageData is not saving on Image annotationBug
ANNOTATIONNET-1461Restore image from ImageDataBug
ANNOTATIONNET-1426Incorrect vertical position of the text annotations on Excel files.Bug
ANNOTATIONNET-1425Exception ‘Failed extract annotations from images’ during removing annotations from PNG.Bug
ANNOTATIONNET-1424Stream is used by another process after Images CleanUpBug
ANNOTATIONNET-1415Corrupted or damaged file errorBug
ANNOTATIONNET-1420Saving Html with Images throws exceptionBug
ANNOTATIONNET-1334Annotations available after removing.Bug
ANNOTATIONNET-1335Error during generating preview for password-protected document.Bug
ANNOTATIONNET-1336Unexpected error with message “The image file format may be not supported at the moment.” for Jpg.Bug
ANNOTATIONNET-1178FilteringAnnotationTypes example raised and exceptionBug
ANNOTATIONNET-1184Background color for highlight annotation is not set in ImagesBug
ANNOTATIONNET-1132Issue with one page PDF preview generatingBug
ANNOTATIONNET-1133Wrong Slides preview generatingBug
ANNOTATIONNET-1145Compatibility issues under .NET Standard 2.0Bug
ANNOTATIONNET-1103Issue with saving formats in PresentationsBug
ANNOTATIONNET-1104Issue with Word Processing documents cleanupBug
ANNOTATIONNET-1106Issue with cleanup Link annotation on PresentationsBug
ANNOTATIONNET-1219Example Code throws NullReferenceException for SpreadSheetBug
ANNOTATIONNET-1240Fix Dwg File SupportBug
ANNOTATIONNET-1242Distance annotation was added in wrong place in jpg fileBug
ANNOTATIONNET-1243Font color was changed after removing text redaction annotationBug
ANNOTATIONNET-1245Remove residual files after Image Annotation workBug
ANNOTATIONNET-1246Encrypted SpreadSheet(Cells) files throws exceptionBug
ANNOTATIONNET-1247Issue with AnnotationType byte FlagBug
ANNOTATIONNET-1257Exception while deleting work files when adding ImageAnntationBug
ANNOTATIONNET-1296Cannot access a closed StreamBug
ANNOTATIONNET-1284Encrypted Excel spreadsheet file throws exceptionBug
ANNOTATIONNET-1321CleanUp method for PowerPoint presentation does not remove repliesBug
ANNOTATIONNET-1370Adding annotations to PNG image makes background non transparentBug
ANNOTATIONNET-1368Unable to Save document as file that was used to create annotatorBug
ANNOTATIONNET-1367A generic error occurred in GDI+ when processing Slides documentsBug
ANNOTATIONNET-1362TextAnnotations not cleaning in Cells after adding VersionsBug
ANNOTATIONNET-1361Comments not cleaned in Excel filesBug
ANNOTATIONNET-1358Wrong file metadata issue in Images after adding VersionsBug
ANNOTATIONNET-1357Empty PagesInfo for Excel file in MVC project.Bug
ANNOTATIONJAVA-1217Exception occurred while remove annotations from xls fileBug
ANNOTATIONJAVA-1238Add DWG files supportBug
ANNOTATIONJAVA-1240Remove underline annotation doesn’t workBug
ANNOTATIONJAVA-1241Font color was changed after removing text redaction annotationBug
ANNOTATIONJAVA-1243Cannot add annotations to the image.Bug
ANNOTATIONJAVA-1245Distance annotation in jpg fileBug
ANNOTATIONJAVA-1312Remove annotation via AnnotationType.None dosen’t workBug
ANNOTATIONJAVA-1311Error when save Text Redaction annotation to fileBug

Public API and Backward Incompatible Changes

  1. Add Image Annotation

    Image annotation allows to add image within document page like shown at the picture below.

    There is an ability to specify the next properties for ImageAnnotation type:

    • ImagePath - defines image local or remote path. Warning, if you use remote path - you need to remove http and https protocol, or www if it present. This error is now investigating.

    Not Correct: https://www.google.com.ua/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png http://www.google.com.ua/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png

    Correct: www.google.com.ua/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png google.com.ua/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png

    • Box - defines annotation position at document page; (image will be resized for your custom width and height)
    • Opacity - allows to set annotation opacity (present in all supported formats, examples of it you can see above);

    Follow these steps to add Image annotation to document:

    • Instantiate Annotator object with input document path or stream;
    • Instantiate ImageAnnotation object with desired properties (position, page number, etc);
    • Call Add method and pass ImageAnnotation object;
    • Call Save method with resultant document path or stream.

    The following code demonstrates how to add ImageAnnotation with remote ImagePath to the document:

    try (Annotator annotator = new Annotator("input.pdf")) {
        ImageAnnotation imageAnnotation = new ImageAnnotation();
        imageAnnotation.setBox(new Rectangle(100, 100, 100, 100));
        imageAnnotation.setOpacity(0.7);
        imageAnnotation.setPageNumber(0);
        imageAnnotation.setImagePath("www.google.com.ua/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png");
        imageAnnotation.setAngle(100.0);
    
        annotator.add(imageAnnotation);
        annotator.save("result.pdf");
    }
    

    The result would be

  2. Added new overloads for Get method

    On version 20.2 was added new overload of Annotator.Get method. It allows to get list of annotation of specific type

    try (Annotator annotator = new Annotator("annotated.pdf")) {
        List<AnnotationBase> tmp = annotator.get(AnnotationType.Area);
    }
    
  3. Added new overloads for Remove method
    On version 20.2 Was added new overload of Annotator.Remove method. New overloads method allow to remove single Annotation or list of Annotations. Follow these steps to add annotation to document:

    • Instantiate Annotator object with input document path or stream;
    • Call Remove method and give them id, list of id’s, annotation to delete, or list of annotations
    • Call Save method to save changes
    1. Following code demonstrates overload how to remove Annotation from Document using annotation index:
    try (Annotator annotator = new Annotator("result.xlsx")) {
        annotator.remove(0);
        annotator.save("removed.xlsx");
    }
    
    1. Following code demonstrates overload how to remove Annotation from Document using Annotation Object:
    try (Annotator annotator = new Annotator("result.xlsx")) {
        List<AnnotationBase> tmp = annotator.get();
        annotator.remove(tmp.get(0));
        annotator.save("removed.xlsx");
    }
    
    1. Following code demonstrates overload how to remove some Annotations from Document using list of Id’s:
    try (Annotator annotator = new Annotator("result.xlsx")) {
        java.util.List<Integer> idList = new java.util.ArrayList<>();
        idList.add(0);
        idList.add(1);
        annotator.remove(idList);
        annotator.remove(idList);
        annotator.save("removed.xlsx");
    }
    
    1. Following code demonstrates how to remove some Annotations from Document using list of Annotations:
    try (Annotator annotator = new Annotator("result.xlsx")) {
        List<AnnotationBase> tmp = annotator.get();
        annotator.removeInternal(tmp);
        annotator.save("removed.xlsx");
    }
    
  4. Starting from version 21.7 several Save methods overloads was added for user convenience
    Now you can call Empty Save to save documents as input file for annotator. If you need to add some options, you may call Save method with only one parameter - SaveOptions, it will do the same as empty but will consider your options.

    1. Method accepts SaveOption parameter
    try (Annotator annotator = new Annotator(_resultPath)) {
        SaveOptions saveOptions = new SaveOptions();
        saveOptions.setVersion(1);
        annotator.save(saveOptions);
    }
    
    1. Empty Save Method
    try (Annotator annotator = new Annotator(_resultPath)) {
        annotator.save();
    }
    
  5. From this time Annotation Models overload the standard Equals method and also implement the IEquatable interface with the type of the class from which this method is called. Example how to use it:

    try (Annotator annotator = new Annotator("annotated_file.pdf")) {
        List<AnnotationBase> annotations = annotator.get();
        ImageAnnotation imageAnnotation = new ImageAnnotation();
        imageAnnotation.setBox(new Rectangle(100, 100, 100, 100));
        imageAnnotation.setOpacity(0.7);
        imageAnnotation.setPageNumber(0);
        imageAnnotation.setImagePath("www.google.com.ua/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png");
        imageAnnotation.setAngle(100.0);
    
        annotator.add(imageAnnotation);
        annotator.save("result.pdf");
    
        for(int i = 0; i < annotations.size(); i++) {
            if (imageAnnotation.equals(annotations.get(i))) {
                    // Do some stuff here...
            }
        }
    }
    
  6. Removed the deprecated ImportAnnotations property from the LoadOptions class because annotations are imported automatically. So, if before version 21.7 this code was correct:

    LoadOptions loadOptions = new LoadOptions();
    loadOptions.setPassword("password");
    loadOptions.setImportAnnotations(true);
    try (Annotator annotator = new Annotator("input.pdf", loadOptions)) {}
    

    Beginning with version 21.7, LoadOptions no longer has the ImportAnnotations property. The previous code needs to be changed. Example:

    LoadOptions loadOptions = new LoadOptions();
    loadOptions.setPassword("password");
    try (Annotator annotator = new Annotator("input.pdf", loadOptions)) {}
    
  7. New WorksheetColumns property in PreviewOptions class that allows to specify the range of generated columns on a specified worksheet.

    Example how to use it:

    PreviewOptions previewOptions = new PreviewOptions(new CreatePageStream() {
        @Override
        public OutputStream invoke(int pageNumber) { //Stream => InputStream
            String pagePath = "/result_{pageNumber}.png";
            return File.create(pagePath).toOutputStream();
        }
    });
    
    previewOptions.getWorksheetColumns().add(new WorksheetColumnsRange("Sheet1", 2, 3));
    previewOptions.getWorksheetColumns().add(new WorksheetColumnsRange("Sheet1", 1, 1));
    
    try (Annotator annotator = new Annotator("input.xlsx")) {
        annotator.getDocument().generatePreview(previewOptions);
    }
    
  8. Versions of Annotated files

    Every Time you Save file using Annotator.Save() method - you implicitly create a new version of the annotated file. Versions List stores not document, it keeps annotations that you add, remove, and change. So you can easy swap between different changes made with GroupDocs.Annotation. And of course you can set your version names. More information about how it works you can find in child Pages

    By default, they are created using unique GUID keys. Next, each aspect of using versions will be considered. The API execution logic has not changed, so you do not need to change your code to use it as before. By default, the latest version is loaded without your fate (that is, you will not notice the difference with previous releases).

    1. Backward Compatibility

    The update is fully compatible with previous and next updates (The latest saved version will be used), however, using versions on previous versions is not possible and the list of versions in this document will not be changed. And If you update file from 20.4+ using 20.2 and lower few times, after loading this document on 20.4+ only last changes will be added as new version.

    1. Add Version with custom name

    If you want to swap between versions easily you might need to have ability to set custom versions names.

    Here the code that demonstrates how to save version with custom name:

    try (Annotator annotator = new Annotator("input.pdf")) {
        AreaAnnotation areaAnnotation = new AreaAnnotation();
        areaAnnotation.setBox(new Rectangle(100, 100, 100, 100));
        annotator.update(areaAnnotation);
        SaveOptions saveOptions = new SaveOptions();
        saveOptions.setVersion("CUSTOM_VERSION" );
        annotator.save("result.pdf", saveOptions);
    }
    
    1. Get List of All version keys on a document

    If you don’t know what versions were added earlier or want to know versions count Here the code that demonstrates how to get list of versions keys:

    try (Annotator annotator = new Annotator("result.pdf")) {
        List<Object> versionKeys = annotator.getVersionsList();
    }
    
    1. Get List of Annotations using version key

    If you need to get List of Annotations you can use Annotator.GetVersion() method Here code that demonstrates how to get list of annotations from individual version

    try (Annotator annotator = new Annotator("result.pdf")) {
        List<AnnotationBase> versionKeys = annotator.getVersion("CUSTOM_VERSION");
    }
    
    1. Load Document of custom Version

    Using LoadOptions.Version you can load previous versions of annotated document. Here the code that demonstrates how load version using version name:

    LoadOptions loadOptions = new LoadOptions();
    loadOptions.setVersion("CUSTOM_VERSION");
    try (Annotator annotator = new Annotator("input.pdf", loadOptions)) {
        annotator.save("result_loaded.pdf");
    }
    
  9. Added RenderComments Property to PreviewOptions If you need not to generate comments on image preview you may use RenderComments property

    Default value is true. If it is not needed to display replies and comments at the page preview - set RenderComments property to false (replies and comments still will be stored inside document).
    Please notice, that RenderComments value will impact any document comments (doesn’t matter if they were added by GroupDocs.Annotation or some other application). Here the code that demonstrates how display image preview without comments:

    Annotator annotator = new Annotator("inputPath");
    PreviewOptions previewOptions = new PreviewOptions(new CreatePageStream() {
        @Override
        public OutputStream invoke(int pageNumber) {
            String pagePath = resultPath.replace("result.pdf", "/result_{pageNumber}.png");
            return File.create(pagePath).toOutputStream();
        }
    })
    previewOptions.setPreviewFormat(PreviewFormats.PNG);
    previewOptions.setRenderComments(false);
    annotator.getDocument().generatePreview(previewOptions);
    
  10. Add PagesInfo property to IDocumentInfo PagesInfo represents list of PageInfo objects which store information about each page.

    Now PageInfo have two properties - Width and Height in pixels. This properties works with all formats except Email And Html that doesn’t have height and width so the won’t store them and will be empty. All pages width and height will be same in all formats except Cells, so you can use size of first element as size of all document.

    Here code that demonstrates how to get Document width and Height:

    Annotator annotator = new Annotator("input.docx");
    IDocumentInfo info = annotator.getDocument().getDocumentInfo();
    int width = info.getPagesInfo().get(0).getWidth();
    int height = info.getPagesInfo().get(0).getHeight();
    
  11. Added Angle property for ImageAnnotation To set a custom angle for ImageAnnotation, you can use the new Angle property. Angle is measured in degrees.

    Example how to use it:

    ImageAnnotation imageAnnotation = new ImageAnnotation();   
    imageAnnotation.setBox(new Rectangle(100, 100, 100, 100));
    imageAnnotation.setOpacity(0.7);
    imageAnnotation.setPageNumber(0);
    imageAnnotation.setImagePath("image.png");
    imageAnnotation.setAngle(90.0);
    
  12. Added horizontal and vertical alignment for Watermark To set Horizontal and Vertical Alignments for WatermarkAnnotation, you can use Alignment properties.

    WatermarkAnnotation watermarkAnnotation = new WatermarkAnnotation();
    watermarkAnnotation.setVerticalAlignment(VerticalAlignment.Bottom);
    watermarkAnnotation.setHorizontalAlignment(HorizontalAlignment.Left);
    
  13. Added text horizontal alignment for TextField To set a text horizontal alignment you can use the TextHorizontalAlignment property.

    TextFieldAnnotation textFieldAnnotation = new TextFieldAnnotation();
    textFieldAnnotation.setTextHorizontalAlignment(HorizontalAlignment.Left);