LEADTOOLS Support
Imaging
Imaging SDK Questions
Objective-C: How to Load TIFF, Burn-in Annotations, and Save with No UI
#1
Posted
:
Thursday, December 23, 2021 12:10:04 PM(UTC)
Groups: Registered
Posts: 2
I want to:
1. Load a TIFF image.
2. Burn-in annotations from an LT annotations XML file.
3. Save the modified image in a different file.
All of this without displaying the image in a UI.
Loading and saving is no problem. It's the burning-in that is giving me headaches.
I can't seem to create an offscreen context to do the burn.
What am I missing/doing wrong? HELP!
Code:-(int)weekendAtBurnies
{
int rc = 0;
NSError *error;
// work from user/Downloads
NSFileManager *fm = [NSFileManager defaultManager];
NSURL *downloadsURL = [fm URLForDirectory:NSDownloadsDirectory
inDomain:NSUserDomainMask
appropriateForURL:nil
create:YES
error:&error];
NSURL *furl = [NSURL URLWithString:@"ocr1.tif" relativeToURL:downloadsURL]; // source image
NSURL *aurl = [NSURL URLWithString:@"A_0.tif" relativeToURL:downloadsURL]; // saved image
NSURL *xurl = [NSURL URLWithString:@"redact.ann.xml" relativeToURL:downloadsURL]; // anno xml
// create annotation container from xml
LTAnnCodecs *annCodecs = [[LTAnnCodecs alloc] init];
NSString *xmlData = [NSString stringWithContentsOfURL:xurl usedEncoding:nil error:&error];
NSLog(@"%@", xmlData);
LTAnnContainer * container = [annCodecs loadXmlData:xmlData pageNumber:1];
// list them
for (int i = 0; i < container.children.count; i++)
{
LTAnnObject *annObj = container.children[i];
NSLog(@"%@\n", [annObj friendlyName]);
}
LTRasterCodecs *codecs =[[LTRasterCodecs alloc] init];
LTRasterImage *sourceImage = [codecs loadURL:furl error:&error];
BOOL setResolution = NO;
int imageDpiX = 0;
int imageDpiY = 0;
if (sourceImage.xResolution != 72 || sourceImage.yResolution != 72)
{
setResolution = YES;
imageDpiX = (uint)sourceImage.xResolution;
imageDpiY = (uint)sourceImage.yResolution;
}
LTAnnContainerMapper *mapper = [container.mapper copy];
container.mapper = [[LTAnnContainerMapper alloc] initWithSourceDpiX:sourceImage.xResolution
sourceDpiY:sourceImage.yResolution
targetDpiX:sourceImage.xResolution
targetDpiY:sourceImage.yResolution];
[sourceImage.linkedImage lockFocus];
CGImageRef imgRef = [LTRasterImageConverter convertToCGImage:sourceImage
options:LTConvertToImageOptionsNone
error:&error];
NSBitmapImageRep *refrep = [[NSBitmapImageRep alloc] initWithCGImage:imgRef];
//
// this always returns nil. WHY! WHY! WHY!
NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithBitmapImageRep:refrep];
//
[NSGraphicsContext saveGraphicsState];
CGContextRef contextRef = [context CGContext];
CGContextTranslateCTM(contextRef, 0, sourceImage.height);
CGContextScaleCTM(contextRef, 1, -1);
// render annotations onto source image
LTAnnUniversalRenderingEngine *renderingEngine = [[LTAnnUniversalRenderingEngine alloc] init];
[renderingEngine attachContainer:container context:contextRef];
//We will use the burnScaleFactor property to burn the objects with fixed states correctly
LeadRectD testRect = [container.mapper rectFromContainerCoordinates:LeadRectDMake(0, 0, 10, 10) operations:(LTAnnFixedStateOperationsNone)];
LeadRectD scaledRect = [mapper rectFromContainerCoordinates:LeadRectDMake(0, 0, 10, 10) operations:(LTAnnFixedStateOperationsNone)];
double scaleFactor = scaledRect.width / testRect.width;
container.mapper.burnScaleFactor /= scaleFactor;
[renderingEngine burn];
[NSGraphicsContext restoreGraphicsState];
[sourceImage.linkedImage unlockFocus];
[renderingEngine detach];
// save rendered image into dest.
LTCodecsImageInfo *info = [codecs imageInformationForURL:furl totalPages:YES error:&error];
[codecs save:sourceImage url:aurl format:LTRasterImageFormatTif bitsPerPixel:info.bitsPerPixel error:&error];
return rc;
}
#2
Posted
:
Monday, October 2, 2023 4:22:07 PM(UTC)
Groups: Registered
Posts: 12
Thanks: 4 times
-(int)weekendAtBurnies
{
int rc = 0;
NSError *error;
// Work from user/Downloads
NSFileManager *fm = [NSFileManager defaultManager];
NSURL *downloadsURL = [fm URLForDirectory:NSDownloadsDirectory
inDomain:NSUserDomainMask
appropriateForURL:nil
create:YES
error:&error];
NSURL *furl = [NSURL URLWithString:@"ocr1.tif" relativeToURL:downloadsURL]; // Source image
NSURL *aurl = [NSURL URLWithString:@"A_0.tif" relativeToURL:downloadsURL]; // Saved image
NSURL *xurl = [NSURL URLWithString:@"redact.ann.xml" relativeToURL:downloadsURL]; // Annotation XML
// Create annotation container from XML
LTAnnCodecs *annCodecs = [[LTAnnCodecs alloc] init];
NSString *xmlData = [NSString stringWithContentsOfURL:xurl usedEncoding:nil error:&error];
NSLog(@"%@", xmlData);
LTAnnContainer *container = [annCodecs loadXmlData:xmlData pageNumber:1];
// List annotations
for (int i = 0; i < container.children.count; i++)
{
LTAnnObject *annObj = container.children[i];
NSLog(@"%@\n", [annObj friendlyName]);
}
LTRasterCodecs *codecs = [[LTRasterCodecs alloc] init];
LTRasterImage *sourceImage = [codecs loadURL:furl error:&error];
// Check image resolution
BOOL setResolution = NO;
int imageDpiX = 0;
int imageDpiY = 0;
if (sourceImage.xResolution != 72 || sourceImage.yResolution != 72)
{
setResolution = YES;
imageDpiX = (int)sourceImage.xResolution;
imageDpiY = (int)sourceImage.yResolution;
}
// Create an offscreen context for burning annotations
CGContextRef contextRef = [LTRasterImageConverter createContextForImage:sourceImage];
// Render annotations onto the source image
LTAnnUniversalRenderingEngine *renderingEngine = [[LTAnnUniversalRenderingEngine alloc] init];
[renderingEngine attachContainer:container context:contextRef];
[renderingEngine burn];
// Save rendered image into destination
[codecs save:sourceImage url:aurl format:LTRasterImageFormatTif bitsPerPixel:LTRasterImageBitsPerPixel8 error:&error];
// Clean up
[renderingEngine detach];
CGContextRelease(contextRef);
return rc;
}
Try this
LEADTOOLS Support
Imaging
Imaging SDK Questions
Objective-C: How to Load TIFF, Burn-in Annotations, and Save with No UI
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.