|
@@ -1,415 +0,0 @@
|
|
|
-//
|
|
|
-// 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 <PDF_Master-Swift.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 setTitleColorWithColor:[NSColor labelColor] font:nil];
|
|
|
-
|
|
|
- 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
|