Set initial size of custom stamps

Product:
WebViewer

Product Version:
10.10.1

Please give a brief summary of your issue:
How to set an initial size for custom stamps without resizing images

Please describe your issue and provide steps to reproduce it:

So this is my code for adding some more stamps to WebViewer. I’m adding them to the “Standard Stamps” section, because I want them to be visible first thing.

To be clear, this works and I don’t have any technical issues with it. I’m also using React, but I don’t think that’s particularly relevant here.

const stampTool = viewerInstance.current.Core.documentViewer.getTool('AnnotationCreateRubberStamp');

stampTool.setStandardStamps([
  '/stamps/some_stamp.png',
  '/stamp/other_stamp.png',
  // Add the default WebViewer stamps, too
  ...stampTool.getStandardStamps(),
]);

My question is, how can I set the size of these custom stamps somehow, so they’re not too big to start. Because currently, users almost always have to resize them down considerably when they first add them to a document. Which is a bit of a nuisance.

Obviously resizing the actual image files might help, but they’re small enough as it is, and I don’t want to make them too blurry by reducing their resolution. They are PNG and JPG files, for reference.

I’d like to know if there’s a good way to do this. Let me know if I should provide more context. Thanks.

1 Like

Hi there,

You can use the annotation manager’s annotationChanged event

or you can use the stamp tool’s annotationAdded event:
https://docs.apryse.com/api/web/Core.Tools.StampCreateTool.html#event:annotationAdded__anchor

to get access to the annotation being added and then adjust the size of the annotation accordingly.

An example of this using the annotationChanged event is available in this forum post:

Best regards,
Kevin Kim

Thanks for the response. That’s getting me most of the way there. I still have a few questions.

My code so far borrows heavily from the linked example. It works, but there are some issues for my particular application.

viewerInstance.current.Core.annotationManager.addEventListener('annotationChanged', (annots, action, {imported}) => {
  if (!imported) {
    for (const annot of annots) {
      if (annot instanceof viewerInstance.current.Core.Annotations.StampAnnotation && action === 'add') {
        annot.Width = 128;
        annot.Height = 128;
        viewerInstance.current.Core.annotationManager.redrawAnnotation(annot);
      }
    }
  }
});

One issue is the imported doesn’t do what I thought it would. What I’m trying to do is stop the resizing from occurring on the provided “Approved”, “As Is”, “Completed”, etc. stamps. Because they’re good the way they are.

The other issue I’m running into is that the stamps I want to add aren’t necessarily squares. Is there any way to obtain the aspect ratio ahead of changing the width and height of the annotation? Or perhaps a way to just change the width OR the height, but keep the original aspect ratio? Because one dimension of 128 works for my application, but I don’t want them to get warped in the resizing process.

Thanks again.

1 Like

Hi there,

One issue is the imported doesn’t do what I thought it would. What I’m trying to do is stop the resizing from occurring on the provided “Approved”, “As Is”, “Completed”, etc. stamps. Because they’re good the way they are.

The imported flag is generally for annotations that are already in the document or using importAnnotations API.

To only resize your custom stamps, you would need to differentiate them and the other stamps you added to setStandardStamps. One idea would be to use an array of defaultStandardStamps and check against them.
Here’s a very rough prototype:

const stampTool = documentViewer.getTool(Tools.ToolNames.RUBBER_STAMP)
const defaultStandardStamps = await stampTool.getStandardStamps() // or define them manually

annotationManager.addEventListener('annotationChanged', (annots, action, { imported }) => {
  if (!imported) {
    for (const annot of annots) {
      if (annot instanceof Annotations.StampAnnotation && action === 'add') {
        // check if part of default stamp
        let isDefaultStamp = false;
        defaultStandardStamps.forEach(stampName => {
          if (annot.Subject === stampName) {
            isDefaultStamp = true;
          }
        })
        if (!isDefaultStamp) {
          console.log('new stamp')
          annot.Width = 128;
          annot.Height = 128;
          annotationManager.redrawAnnotation(annot);
        }
      }
    }
  }
});

For stamp annotations, you can use the MaintainAspectRatio property:
https://docs.apryse.com/api/web/Core.Annotations.StampAnnotation.html#MaintainAspectRatio__anchor

Best regards,
Kevin Kim

1 Like

Thanks. I like that concept.

However, this is what I’m getting as the list of default stamps:

From const defaultStamps = stampTool.getStandardStamps();

But it’s kind of inconsistent which annotation titles line up with these or not. Like there’s Rejected instead of SBRejected from the default list. For Public Release instead of ForPublicRelease, etc.

And I also tried using the MaintainAspectRatio property, but I don’t know where to set it for it to be effective.

1 Like

It looks like you want to use the Icon property instead of Subject property, this will match by the names returned from getStandardStamps.

The MaintainAspectRatio property is for the stamp annotation, so you should be able to set it on creation, i.e. where you set the width/height of the annotation.

Best regards,
Kevin Kim

1 Like

Thank you. Unfortunately I still don’t have a full solution for this issue. Although I think we’re getting very close.

For some reason my custom icons have the Icon and Subject of “Draft”, which is the same as a standard stamp. That’s not that big of a deal, though.

But I also tried setting the MaintainAspectRatio property before adding the custom annotations. Maybe I’m still missing something here, but it just seems like it has no effect. And the annotations still come out squashed if they aren’t perfectly square to begin with.

if (annot.Icon === 'Draft')) {
  annot.MaintainAspectRatio = true;
  annot.Width = 128;
  annot.Height = 128;
  viewerInstance.current.Core.annotationManager.redrawAnnotation(annot);
}

I also tried just changing the height, or just changing the width. But MaintainAspectRatio doesn’t seem to help there, either. It also seems to be set to true on these custom stamps by default, even if I don’t set it.

1 Like

For the ‘Draft’ Icon, you can rename the Icon properties for your custom annotations to avoid that issue.

Regarding MaintainAspectRatio, it seems like it is set to true by default, and I can see that it is resizing while maintaining the aspect ratio.
Sample code used:

const stampTool = documentViewer.getTool(Tools.ToolNames.RUBBER_STAMP)

// sample png
stampTool.setStandardStamps([
  'https://png.pngtree.com/png-vector/20220315/ourmid/pngtree-sample-stamp-ink-sample-vector-png-image_16532122.png'
]);

annotationManager.addEventListener('annotationChanged', (annots, action, { imported }) => {
  let annot = annots[0]
  annot.Width = 128;
  annot.Height = 128;
  annot.MaintainAspectRatio = true
  annotationManager.redrawAnnotation(annot);
});

Could you share your full code snippet and a video showing the resizing the annotation with expected vs actual output?

Best regards,
Kevin Kim

1 Like

Good thinking.

OK, well here’s a CodeSandbox illustrating that this issue persists, at least for me, with a minimal setup pretty similar to what I’m trying to do.

https://codesandbox.io/p/devbox/3prct3

1 Like

Hi there,

It looks like the aspect ratio of the stamp is maintained when resizing, please see this video for reference:
Screen Recording 2024-10-29 at 12.30.43 PM.mov

Best regards,
Kevin Kim

1 Like

Oh. Right. Perhaps there’s a misunderstanding, then. Sorry if I’ve been unclear. Thanks for the confirmation that that’s what the MaintainAspectRatio property does - maintain the aspect ratio of an annotation while resizing it.

But the issue I’ve been running into is that I want to resize all custom stamps to a certain size, without squishing the non-square ones when changing their width/height. I’m just not sure if there’s a good way to do that, without having the original sizes of the images. Because currently, this method only works if all the annotation images I want to resize have the same aspect ratio in the first place.

Is there some WebViewer API that could handle that, or would I have to figure that out some other way? I would be looking for the original size and/or aspect ratio of the annotation image before adding it to the scene.

Otherwise, I think I can figure out a solution, but I am curious to know if there is a feature in WebViewer that would allow for this. Thanks again, and sorry for any miscommunication on my part.

1 Like

Hi there,

But the issue I’ve been running into is that I want to resize all custom stamps to a certain size, without squishing the non-square ones when changing their width/height.

Like you mentioned, unless you know the dimensions of the image before hand, this will most likely happen when you resize the images with fixed width and height.

You could get the annotation object that’s in the stamp tool, i.e.

const stampAnnotations = await stampTool.getStandardStampAnnotations()
const stampHeight = stampAnnotations[0].getHeight()
const stampWidth = stampAnnotations[0].getWidth()

// Then adjust the annotation's width/height using the above proportions

best regards,
Kevin Kim

1 Like

Thanks! Here’s what I came up with. I probably should have tried this earlier, but for some reason I didn’t think it worked.

const stampTool = viewerInstance.current.Core.documentViewer.getTool(viewerInstance.current.Core.Tools.ToolNames.RUBBER_STAMP);

const defaultStandardStamps = stampTool.getStandardStamps().filter(a => a !== 'Draft');

stampTool.setStandardStamps([
  '/some/stamp.png',
   // Add the default WebViewer stamps
   ...defaultStandardStamps,
]);

viewerInstance.current.Core.annotationManager.addEventListener('annotationChanged', async (annots, action, {imported}) => {
  if (!imported) {
    for (const annot of annots) {
      if (annot instanceof viewerInstance.current.Core.Annotations.StampAnnotation && action === 'add') {
        if (!defaultStandardStamps.some(name => annot.Icon === name)) {
          // Resize the stamp while maintaining its aspect ratio
          const aspectRatio = annot.Width / annot.Height;
          annot.Width = Math.round(64 * aspectRatio);
          annot.Height = 64;

          viewerInstance.current.Core.annotationManager.redrawAnnotation(annot);
        }
      }
    }
  }
});

Anyway, this solves my main issue, but I still have a couple minor questions.

First, I’m still not sure how I can rename my custom stamps so they don’t have the “Draft” icon property. At the moment I’m just not including the default “Draft” icon, so it doesn’t get caught up in this logic. Because I don’t need to resize it.

And from this thread:

It seems like the resizing of the preview that pops up when you select a stamp isn’t supported, at least as of last year. If that is still the case, that’s fine. I was just curious as to whether it is now supported.

1 Like

It looks like the annotations you add to the standardStamp list can be differentiated by the ‘src’ property.
For instance, you could do something like this:

const stampTool = documentViewer.getTool(Tools.ToolNames.RUBBER_STAMP)
const defaultStandardStamps = await stampTool.getStandardStamps()

// sample png
stampTool.setStandardStamps([
  'https://png.pngtree.com/png-vector/20220315/ourmid/pngtree-sample-stamp-ink-sample-vector-png-image_16532122.png',
    ...defaultStandardStamps 
]);

const savedStampAnnotations = await stampTool.getStandardStampAnnotations()
savedStampAnnotations.filter(async stampAnnotation => {
    if (await stampAnnotation.getImageData()){
        // your operation here
    }
})

However you will need to catch the error due to the default stamps not having an image src.

Alternatively, if you don’t need the default ‘DRAFT’ stamp, you can remove that from the set of standard stamps and reference all the custom stamps as ‘DRAFT’.

Regarding the stamp preview resizing, this hasn’t been implemented yet and is still in the backlog for the product team to review.

Best regards,
Kevin Kim

1 Like

Alright. That works for me.
Thanks for bearing with my questions and misunderstandings. I got a solution I’m happy with now.

1 Like