123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- //
- // KMPDFSignatureImageView.m
- // PDF Reader
- //
- // Created by 丁林圭 on 2018/6/8.
- // Copyright © 2018年 Kdan Mobile. All rights reserved.
- //
- #import "KMPDFSignatureImageView.h"
- #import <Quartz/Quartz.h>
- #import "KMImageAccessoryController.h"
- #import "NSButton+TitleColor.h"
- #define KMSignatureMaxWidth 400
- #define KMSignatureMaxHeight 300
- @interface KMPDFSignatureImageView()
- @property (nonatomic, retain) NSImage * picImage;
- @property (nonatomic) IBOutlet NSView *pictureView;
- @property (nonatomic) IBOutlet NSTextField *emptyTipLbl;
- @property (nonatomic) IBOutlet NSButton *dragButton;
- @property (nonatomic) IBOutlet NSImageView *emptyImg;
- @property (nonatomic, copy) NSTrackingArea *trackingArea;
- @property (nonatomic, strong) NSURL *imageURL;
- @end
- @implementation KMPDFSignatureImageView
- - (void)dealloc {
- [self removeTrackingArea:self.trackingArea];
- }
- - (id)initWithFrame:(NSRect)frameRect
- {
- if (self = [super initWithFrame:frameRect])
- {
- self.wantsLayer = YES;
- self.layer.borderWidth = 1.0;
- self.layer.borderColor = [NSColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.05].CGColor;
- self.layer.backgroundColor = [NSColor colorWithRed:1 green:1 blue:1 alpha:0.9].CGColor;;
-
- [self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
-
- }
- return self;
- }
- - (void)awakeFromNib
- {
- [super awakeFromNib];
-
- self.emptyTipLbl.stringValue = NSLocalizedString(@"Select image file", nil);
- self.emptyTipLbl.textColor = [NSColor labelColor];
- self.dragButton.wantsLayer = YES;
- [self.dragButton setTitleColor:[NSColor labelColor]];
-
- self.pictureView.wantsLayer = YES;
- self.emptyImg.image = [NSImage imageNamed:@"signPicture_nor"];
-
- self.trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
- options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveAlways
- owner:self
- userInfo:nil];
- [self addTrackingArea:self.trackingArea];
- }
- - (NSArray *)supportedImageTypes
- {
- return [NSArray arrayWithObjects:@"jpg",@"cur",@"bmp",@"jpeg",@"gif",@"png",@"tiff",@"tif",@"ico",@"icns",@"tga",@"psd",@"eps",@"hdr",@"jp2",@"jpc",@"pict",@"sgi",@"pdf", nil];
- }
- - (void)drawRect:(NSRect)dirtyRect
- {
- [super drawRect:dirtyRect];
- if (self.pictureView) {
-
- CGRect rect = NSZeroRect;
- CIImage *imageCIImage = [CIImage imageWithData:self.picImage.TIFFRepresentation];
- NSSize size = [imageCIImage extent].size;
-
- CGFloat scale = MIN((dirtyRect.size.width - 30)/size.width, (dirtyRect.size.height - 30)/size.height);
- if (scale > 1) {
- rect = CGRectMake(0, 0, size.width, size.height);
- } else {
- rect = CGRectMake(0, 0, size.width * scale, size.height *scale);
- }
- [self.picImage drawInRect:CGRectMake((dirtyRect.size.width - rect.size.width)/2,
- (dirtyRect.size.height - rect.size.height)/2,
- rect.size.width,rect.size.height)
- fromRect:NSZeroRect
- operation:NSCompositingOperationSourceOver
- fraction:1.0];
- }
- }
- - (void)setClearBackground:(BOOL)clearBackground {
- _clearBackground = clearBackground;
-
- if (self.imageURL && self.imageURL.path.length > 0) {
- [self loadImageViewPath:self.imageURL isRemoveBGColor:self.clearBackground];
- }
- }
- #pragma mark Public
- - (void)clearImage
- {
- self.picImage = nil;
- self.imageURL = nil;
- self.pictureView.hidden = self.emptyTipLbl.hidden = NO;
- [self setNeedsDisplay:YES];
-
- if (self.changeSignatureImageCallback) {
- self.changeSignatureImageCallback(YES);
- }
- }
- - (void)reSelectImage {
- [self buttonItemClick_SelectPhoto:nil];
- }
- - (NSImage *)signatureImage
- {
- CGRect rect = CGRectZero;
-
- if (!self.picImage) {
- return nil;
- } else {
- CIImage *imageCIImage = [CIImage imageWithData:self.picImage.TIFFRepresentation];
- NSSize size = [imageCIImage extent].size;
- CGFloat scale = MIN(KMSignatureMaxWidth/size.width, KMSignatureMaxHeight/size.height);
- if (scale > 1) {
- rect = CGRectMake(0, 0, size.width, size.height);
- } else {
- rect = CGRectMake(0, 0, size.width * scale, size.height *scale);
- }
- }
-
- NSImage *image = [[NSImage alloc] initWithSize:rect.size];
- [image lockFocus];
- [self.picImage drawInRect:rect
- fromRect:NSZeroRect
- operation:NSCompositingOperationSourceOver
- fraction:1.0];
- [image unlockFocus];
- return image;
- }
- - (void)loadImageViewPath:(NSURL *)url isRemoveBGColor:(BOOL)isRemove
- {
- self.imageURL = url;
-
- NSString * filePath = url.path;
- if ([filePath.pathExtension.lowercaseString isEqualToString:@"pdf"]) {
- PDFDocument *pdf = [[PDFDocument alloc] initWithURL:url];
- if (pdf.isEncrypted) {
- return;
- }
- }
- NSImage *image = [[NSImage alloc] initWithContentsOfFile:filePath];
-
- if (isRemove) {
- NSData *imageData = [image TIFFRepresentation];
- CGImageRef imageRef;
- if (imageData) {
- CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
- imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
- }
-
- const int imageWidth = image.size.width;
- const int imageHeight = image.size.height;
- size_t bytesPerRow = imageWidth * 4;
- uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight);
-
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
- CGContextRef context = CGBitmapContextCreate(rgbImageBuf,
- imageWidth,
- imageHeight,
- 8,
- bytesPerRow,
- colorSpace,
- kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
- CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), imageRef);
-
- int pixelNum = imageWidth * imageHeight;
- uint32_t* pCurPtr = rgbImageBuf;
- for (int i = 0; i < pixelNum; i++, pCurPtr++) {
- uint8_t* ptr = (uint8_t*)pCurPtr;
- if (ptr[1] > 240 && ptr[2] > 240 && ptr[3] > 240) {
- ptr[0] = 0;
- }
- }
-
- CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, nil);
- imageRef = CGImageCreate(imageWidth,
- imageHeight,
- 8,
- 32,
- bytesPerRow,
- colorSpace,
- kCGImageAlphaLast |kCGBitmapByteOrder32Little,
- dataProvider,
- NULL,
- true,
- kCGRenderingIntentDefault);
- CGDataProviderRelease(dataProvider);
-
- NSImage *newImage = nil;
- if (imageRef) {
- NSRect imageRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
- CGContextRef imageContext = nil;
-
- // Get the image dimensions.
- imageRect.size.height = CGImageGetHeight(imageRef);
- imageRect.size.width = CGImageGetWidth(imageRef);
-
- // Create a new image to receive the Quartz image data.
- newImage = [[NSImage alloc] initWithSize:imageRect.size];
- [newImage lockFocus];
-
- // Get the Quartz context and draw.
- imageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
- CGContextDrawImage(imageContext, *(CGRect*)&imageRect, imageRef);
- [newImage unlockFocus];
- CGImageRelease(imageRef);
- }
-
- if (newImage) {
- image = newImage;
- }
- }
-
- if (image) {
- self.picImage = image;
- self.pictureView.hidden = self.emptyTipLbl.hidden = YES;
- [self setNeedsDisplay:YES];
- }
- }
- - (CAGradientLayer *)setGradualChanging {
- CAGradientLayer *gradientLayer = [CAGradientLayer layer];
- gradientLayer.frame = _dragButton.bounds;
- gradientLayer.colors = @[(__bridge id)[NSColor lightGrayColor].CGColor,(__bridge id)[NSColor whiteColor].CGColor];
- gradientLayer.startPoint = CGPointMake(0, 0);
- gradientLayer.endPoint = CGPointMake(1, 1);
- gradientLayer.locations = @[@0,@1];
- return gradientLayer;
- }
- - (BOOL)isDamageImage:(NSImage *)image imagePath:(NSString *)path {
- NSString *addImageAnnotation = [[[NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier] stringByAppendingPathComponent:@"addImageAnnotation"];
- if (![[NSFileManager defaultManager] fileExistsAtPath:addImageAnnotation]) {
- [[NSFileManager defaultManager] createDirectoryAtPath:addImageAnnotation withIntermediateDirectories:NO attributes:nil error:nil];
- }
- NSData *data = [image TIFFRepresentation];
- NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:data];
- [imageRep setSize:[image size]];
- NSData *imageData = nil;
- if ([path.lowercaseString isEqualToString:@"png"]) {
- imageData = [imageRep representationUsingType:NSBitmapImageFileTypePNG properties:@{}];
- } else {
- imageData = [imageRep representationUsingType:NSJPEGFileType properties:@{}];
- }
-
- NSString *rPath = [addImageAnnotation stringByAppendingPathComponent:[[self tagString] stringByAppendingPathExtension:@"png"]];
- if (![imageData writeToFile:rPath atomically:YES]) {
- return YES;
- } else {
- return NO;
- }
- }
- - (NSString *)tagString {
- NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
- dateFormatter.dateFormat = @"yyMMddHHmmss";
- return [NSString stringWithFormat:@"%@%04d", [dateFormatter stringFromDate:[NSDate date]], rand()%10000];
- }
- #pragma mark - Button Action
- - (IBAction)buttonItemClick_SelectPhoto:(id)sender
- {
- NSOpenPanel *openPanel = [NSOpenPanel openPanel];
-
- [openPanel setAllowedFileTypes:[self supportedImageTypes]];
- [openPanel setAllowedFileTypes:[KMImageAccessoryController supportedImageTypes]];
- if ([openPanel respondsToSelector:@selector(setAccessoryViewDisclosed:)]) {
- [openPanel setAccessoryViewDisclosed:YES];
- }
- [openPanel setAllowsMultipleSelection:NO];
- [openPanel beginSheetModalForWindow:[self window] completionHandler:^(NSInteger result) {
- if (result == NSModalResponseOK) {
-
- NSURL *url = [openPanel URL];
-
- //判断PDF文件是否已损坏
- NSString * filePath = url.path;
- if ([filePath.pathExtension.lowercaseString isEqualToString:@"pdf"]) {
- PDFDocument *pdf = [[PDFDocument alloc] initWithURL:url];
- if (!pdf) {
- NSAlert *alert = [[NSAlert alloc] init];
- [alert setAlertStyle:NSAlertStyleCritical];
- [alert setMessageText:[NSString stringWithFormat:@"%@",NSLocalizedString(@"An error occurred while opening this document. The file is damaged and could not be repaired.", nil)]];
- [alert runModal];
- return;
- }
- }
-
- NSImage *image = [[NSImage alloc] initWithContentsOfFile:url.path];
- if ([self isDamageImage:image imagePath:url.path]) {
- NSAlert *alert = [[NSAlert alloc] init];
- [alert setAlertStyle:NSAlertStyleCritical];
- [alert setMessageText: [NSString stringWithFormat:NSLocalizedString(@"The file \"%@\" could not be opened.", nil), url.path.lastPathComponent]];
- [alert setInformativeText:NSLocalizedString(@"It may be damaged or use a file format that PDF Reader Pro doesn’t recognize.", nil)];
- [alert addButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
- [alert beginSheetModalForWindow:[NSApp mainWindow] completionHandler:^(NSModalResponse returnCode) {
- if (returnCode == NSAlertFirstButtonReturn) {
- }
- }];
- return;
- }
-
- [self loadImageViewPath:url isRemoveBGColor:self.clearBackground];
- if (self.changeSignatureImageCallback) {
- self.changeSignatureImageCallback(YES);
- }
- }
- }];
- }
- - (void)mouseEntered:(NSEvent *)event {
- [super mouseEntered:event];
- self.emptyImg.image = [NSImage imageNamed:@"signPicture_hover"];
- }
- - (void)mouseMoved:(NSEvent *)event {
- [super mouseMoved:event];
-
- CGPoint point = [event locationInWindow];
- CGPoint convertPoint = [self.pictureView convertPoint:point fromView:self.window.contentView];
-
- if (CGRectContainsPoint(self.pictureView.bounds, convertPoint)) {
- self.emptyImg.image = [NSImage imageNamed:@"signPicture_hover"];
- } else {
- self.emptyImg.image = [NSImage imageNamed:@"signPicture_nor"];
- }
- }
- - (void)mouseExited:(NSEvent *)event {
- [super mouseExited:event];
- self.emptyImg.image = [NSImage imageNamed:@"signPicture_nor"];
- }
- #pragma mark - Drag
- - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
- {
- NSPasteboard *pboard = [sender draggingPasteboard];
- if ([pboard availableTypeFromArray:[NSArray arrayWithObject:NSFilenamesPboardType]]) {
- NSArray *fileNames = [pboard propertyListForType:NSFilenamesPboardType];
- if (fileNames.count == 1) {
- NSArray *supportArray= [self supportedImageTypes];
- NSString* path = fileNames.firstObject;
- if ([supportArray containsObject:[path.pathExtension lowercaseString]]) {
- return NSDragOperationEvery;
- }
- }
- }
- return NSDragOperationNone;
- }
- - (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender
- {
- NSPasteboard *pboard = [sender draggingPasteboard];
- if ([pboard availableTypeFromArray:[NSArray arrayWithObject:NSFilenamesPboardType]]) {
- NSMutableArray *fileNames = [pboard propertyListForType:NSFilenamesPboardType];
-
- if (fileNames.count == 1) {
- NSArray *supportArray= [self supportedImageTypes];
- NSString* path = fileNames.firstObject;
-
- //判断PDF文件是否已损坏
- NSString * filePath = path;
- if ([filePath.pathExtension.lowercaseString isEqualToString:@"pdf"]) {
- PDFDocument *pdf = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:path]];
- if (!pdf) {
- NSAlert *alert = [[NSAlert alloc] init];
- [alert setAlertStyle:NSAlertStyleCritical];
- [alert setMessageText:[NSString stringWithFormat:@"%@",NSLocalizedString(@"An error occurred while opening this document. The file is damaged and could not be repaired.", nil)]];
- [alert runModal];
- return NO;
- }
- }
- if ([supportArray containsObject:[path.pathExtension lowercaseString]]) {
- [self loadImageViewPath:[NSURL fileURLWithPath:path] isRemoveBGColor:self.clearBackground];
- if (self.changeSignatureImageCallback) {
- self.changeSignatureImageCallback(YES);
- }
- }
- }
- }
- return YES;
- }
- @end
|