Highlighted

HiDPI and Retina support in Custom UI

New Here ,
Jul 05, 2020

Copy link to clipboard

Copied

Hi there!

I'm drawing an image with the custom UI in a composition window. I'm on Macbook Pro retina display and all image pixels appear to be 2x2 device pixels.
Documentation sais: 

To support HiDPI and Retina Displays, you can use offscreen images that are twice the size, and then use the Transform function to scale the image down in half before drawing it.

I tried it but with no luck, the image appeared to be on a correct place and size, but quality became even worse. Also experimented with different antialiasing polices, but it seems they affect drawbot only.
My current approach is:

 

//Prepare Image twice bigger

Transform( /*with a scale down matrix*/)

DrawImage( /*with the image twice the size*/ )

 

It doesn't solve the issue and Transform operation seems to work in ordinary (not hiDPI) space.
Am I missing something? Is it supported in AE somehow?

Below an example of how currently it looks like:
Screenshot 2020-07-05 at 13.44.11.png

All green pixels a 2x2

 

Cheers!

TOPICS
SDK

Views

54

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

HiDPI and Retina support in Custom UI

New Here ,
Jul 05, 2020

Copy link to clipboard

Copied

Hi there!

I'm drawing an image with the custom UI in a composition window. I'm on Macbook Pro retina display and all image pixels appear to be 2x2 device pixels.
Documentation sais: 

To support HiDPI and Retina Displays, you can use offscreen images that are twice the size, and then use the Transform function to scale the image down in half before drawing it.

I tried it but with no luck, the image appeared to be on a correct place and size, but quality became even worse. Also experimented with different antialiasing polices, but it seems they affect drawbot only.
My current approach is:

 

//Prepare Image twice bigger

Transform( /*with a scale down matrix*/)

DrawImage( /*with the image twice the size*/ )

 

It doesn't solve the issue and Transform operation seems to work in ordinary (not hiDPI) space.
Am I missing something? Is it supported in AE somehow?

Below an example of how currently it looks like:
Screenshot 2020-07-05 at 13.44.11.png

All green pixels a 2x2

 

Cheers!

TOPICS
SDK

Views

55

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Jul 05, 2020 0
Community Beginner ,
Jul 21, 2020

Copy link to clipboard

Copied

Hi Роман, 

 

This code sets antialiasing for the drawing functions to work correctly

 

 

 

DRAWBOT_SurfaceSuite1 **surfaceSuite;
(*surfaceSuite)->SetAntiAliasPolicy(*surface_ref, kDRAWBOT_AntiAliasPolicy_High);

 

 

 

 

This code lets to detect whether AE is displayed on Retina display currently (in case of multi-monitor setup):

 

 

 

float scale = 0;
(*surfaceSuite)->GetTransformToScreenScale(*surface_ref, &scale);
bool isRetina = scale > 1 ? true : false;

 

 

 

 

The same scale parameter should be passed to

 

 

 

DRAWBOT_ImageSuite1 *imageSuite;
imageSuite->SetScaleFactor(imageRef, scale);

 

 

 

 

imageRef is returned NewImageFromBuffer and the buffer for this function should be prepared with having in mind whether the current display is Retina or not and whether Retina display is connected at all.

 

I used the following codes to make this:

 

 

 

static bool isRetinaPresent()
{
    NSImage *image = [[NSCursor arrowCursor] image];
    
    [image lockFocus] ;
    NSBitmapImageRep *imageRepresentation = [[[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect(0.0, 0.0, image.size.width, image.size.height)] autorelease] ;
    [image unlockFocus] ;
    
    if( imageRepresentation.pixelsWide != image.size.width )
        return true;
    
    return false;
}

void ImageAdobe::convertToBuf(bool retinaScreen)
{
    unsigned int width;
    unsigned int height;
    NSBitmapImageRep *imageRep;
    
    if( isRetinaPresent() && !retinaScreen )
    {
        //When Retina display is plugged in all NSImages are scaled even when current display is not Retina
        width = [m_image size].width;
        height = [m_image size].height;
        
        //Downscale for Retina display
        imageRep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
                                                            pixelsWide:width
                                                            pixelsHigh:height
                                                         bitsPerSample:8
                                                       samplesPerPixel:4
                                                              hasAlpha:YES
                                                              isPlanar:NO
                                                        colorSpaceName:NSCalibratedRGBColorSpace
                                                           bytesPerRow:0
                                                          bitsPerPixel:0] autorelease];
        [imageRep setSize:[m_image size]];
        
        [NSGraphicsContext saveGraphicsState];
        [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:imageRep]];
        [m_image drawInRect:NSMakeRect(0, 0, width, height) fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];
        [NSGraphicsContext restoreGraphicsState];
    }
    else
    {
        imageRep = [NSBitmapImageRep imageRepWithData:[m_image TIFFRepresentation]];
        
        width = (unsigned int)[imageRep pixelsWide];
        height = (unsigned int)[imageRep pixelsHigh];
    }

......

 

 

Extract image data using [imageRep bitmapData] and [imageRep bytesPerRow] and convert from RGBA to ARGB

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jul 21, 2020 3
New Here ,
Jul 29, 2020

Copy link to clipboard

Copied

Thanks for the answer!
Unfortunately, it didn't help me with the original question. I've already known how to scale the image, but the issue is that when I draw it all pixels are still twice the actual device pixes. It seems that drawbot doesn't truly support retina displays and can't draw high dpi images. Even all AE tools like roto masks and puppets are blurry on the retina screen because of it. Have you managed to fix this behavior?


For instance here's a zoomed screenshot with mask line. The blue square is a single device pixel, but the line rasterized to 2x2 pixels. Background plate, at the same time, looks ok and uses hi dpi of the screen.

Роман_Белов_0-1596036338987.png

 

Thanks again,

Roman

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jul 29, 2020 0
rkudinov LATEST
Community Beginner ,
Jul 29, 2020

Copy link to clipboard

Copied

Hmm... It appears the plugin I wrote this for is Premiere Pro only (it was a long time ago, I forgot about it).In PPro all images I display with this code look well.

Unfortunately, the plugin doesn't run in After Effects because of PPro dependencies and I can't tell you whether these codes run the same in After Effects.

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jul 29, 2020 0