Start a new topic
Solved

Change Screen Capture Image Quality or Size?

I am using Wikitude CaptureScreen to save a picture to my local storage. 


Then my CaptureScreen Callback takes the file path returned and uses it a parameter for Ionic Native's (File.readAsDataURL). 


I can successfully find the image and convert it to Base64. However, it is REALLY slow. The function takes about 6-10 seconds to complete. 


I looked into the file size in local storage and each image is about 2.5MB. 


Is there anyway to reduce the file size so that the conversion to Base64 is quicker?


Ionic Native's Camera.getPicture method lets you specify a number for quality and the images are a much smaller file size, (~100kb depending on quality setting). The conversion to Base64 is less than a second. 


Thanks! 



Hi Kyle,

Currently you can't change the quality of the screenshot. You could get the screenshot as UIImage and then downscale/convert it to base64. 

For that you would need to change the Wikitude Cordova plugin so that you get the screenshot as UIImage and not stored in the application bundle or Camera Roll album.


Best regards,

Andreas

Hi Andreas, 


Thank you for the reply. 


I am currently looking at the captureScreen method in the wikitude plugin. 


 

captureScreen:(CDVInvokedUrlCommand *)command
{
    CDVPluginResult *pluginResult = nil;


    if (self.arViewController && [self.arViewController.architectView isRunning])
    {
        if ( 2 == command.arguments.count ) // only proceed if the two required parameters are given
        {
            self.screenshotCallbackId = command.callbackId;


            WTScreenshotCaptureMode captureMode = [[command.arguments objectAtIndex:0] boolValue] ? WTScreenshotCaptureMode_CamAndWebView : WTScreenshotCaptureMode_Cam;


            WTScreenshotSaveMode saveMode;
            NSString *screenshotBundlePath = nil;
            if ( [[command.arguments objectAtIndex:1] isKindOfClass:[NSString class]] )
            {
                saveMode = WTScreenshotSaveMode_BundleDirectory;
                screenshotBundlePath = [command.arguments objectAtIndex:1];
            }
            else
            {
                saveMode = WTScreenshotSaveMode_PhotoLibrary;
            }

            WTScreenshotSaveOptions options = WTScreenshotSaveOption_SavingWithoutOverwriting | WTScreenshotSaveOption_CallDelegateOnSuccess;

            [self.arViewController.architectView captureScreenWithMode:captureMode usingSaveMode:saveMode saveOptions:options context: screenshotBundlePath ? @{kWTScreenshotBundleDirectoryKey: screenshotBundlePath} : nil];
        }
    }


    pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT];
    [pluginResult setKeepCallbackAsBool:YES];

    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

 The conditional statement looks like saveMode can only be WTScreenshotSaveMode_BundleDirectory or WTScreenshotSaveMode_PhotoLibrary. Can you tell me how to make the saveMode UIImage? 


Thanks, 


Kyle 

Hi Kyle,

The WTScreenshotSaveMode defines a third type, WTScreenshotSaveMode_Delegate. From the documentation it says:

/** The generated screenshot will be passed to the -architectView:didCaptureScreenWithContext: context dictionary. The key is  kWTScreenshotImageKey. */

    WTScreenshotSaveMode_Delegate           = 3


That should be what you need (The object for the mentioned key should be of type UIImage) ;)


Best regards,

Andreas

Hi Andreas, 


Thank you again for the reply. 


Inside of WTWikitudePlugin.m I made saveMode = WTScreenshotSaveMode_Delegate;


On this line 

[self.arViewController.architectView captureScreenWithMode:captureMode usingSaveMode:saveMode saveOptions:options context: screenshotBundlePath ? @{kWTScreenshotBundleDirectoryKey: screenshotBundlePath} : nil];

 for the context, instead of the ternary, should I make it: 


@{kWTScreenshotImageKey: ??Not Sure What to put here?? }



In the parameters for  WikitudePlugin.captureScreen I have: 

 - Success Callback

- Error Callback

- Boolean for showing web view or not

- ?? not sure what to put here, I was putting my file path when my save mode was BundleDirectory       Does something have to be put into this parameter to be used as the value for kWTScreenshotImageKey

 

Sorry for all of the questions, but I can't find very much documentation about WTScreenshotSaveMode_Delegate or UIImage and I've never really used Obj C. 


Thanks

Hi Kyle,

You're doing just fine. We will find a solution ;)


The changes you made for the save mode seem to be fine. The kWTScreenshotImageKey is important for the `-architectView:didCaptureScreenWithContext` method. The second parameter for this method is a dictionary for what the image key is important. If the save mode is set to delegate, this dictionary contains the UIImage as value for the kWTScreenshotImageKey key. So you need to write something like `UIImage *image = [context objectForKey:kWTScreenshotImageKey];`.

You don't need to make any changes to the WikitudePlugin.captureScreen function as we do the changes in the ObjC part of the plugin.


Best regards,

Andreas

Hi Andreas, 


This is what my capture screen function looks like right now. 


 

#pragma mark Screen Capturing

- (void)captureScreen:(CDVInvokedUrlCommand *)command
{
    CDVPluginResult *pluginResult = nil;

    if (self.arViewController && [self.arViewController.architectView isRunning])
    {

      self.screenshotCallbackId = command.callbackId;

      WTScreenshotCaptureMode captureMode = [[command.arguments objectAtIndex:0] boolValue] ? WTScreenshotCaptureMode_CamAndWebView : WTScreenshotCaptureMode_Cam;
       
      saveMode = WTScreenshotSaveMode_Delegate;
      UIImage *image = [context objectForKey:kWTScreenshotImageKey];
      
      WTScreenshotSaveOptions options = WTScreenshotSaveOption_CallDelegateOnSuccess;
      [self.arViewController.architectView captureScreenWithMode:captureMode usingSaveMode:saveMode saveOptions:options context: image];
    }


    pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT];
    [pluginResult setKeepCallbackAsBool:YES];

    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

 


So far the build is failing when trying to build in Ionic 2.


The build error is happening on the UIImage line. 


This is in the WTWikitudePlugin.m file in the platforms folder of my project. 


Is this the right file to put UIImage *image = [context objectForKey:kWTScreenshotImageKey];


Also what do I need to put as the second argument to the capture screen function after the boolean for screencapture mode? 


Thanks, 

Kyle 

Hi Kyle,

You don't need to change line 12. This only only defines what should be included in the screenshot.

The content of line 16 is pointless here. Within the -captureScreen: method, you only initiate the screenshot generation, so you can't already access the final screenshot. It simply didn't happen yet. You need to read the UIImage from the `context` dictionary that you find in line 783 of WTWikitudePlugin.m. That method is called once the screenshot was generated and the dictionary then contains the generated image.


Best regards,

Andreas 

Thanks Andreas, 


I finally got it working! 


I can now re-scale the UIImage and convert that to Base64 in Obj C, then return the image to my Ionic 2 UI. 


It now takes less than a second! 


Hi Kyle,

Congratulations! I'm glad that everything is working as you wanted it to be.


Best regards,

Andreas

Hi Kyle.
I'm facing the same issue right now. Would you mind sharing the whole code? I tried to follow this topic, but I must admit I'm totally lost in obj-c.

Best regards,
Michal

 

Login or Signup to post a comment