// // KMCropPreviewController.swift // PDF Master // // Created by tangchao on 2022/12/29. // import Cocoa import PDFKit extension CPDFPage { var cropDrawingPage: CPDFPage? { get { return (objc_getAssociatedObject(self, "drawingPage") as! CPDFPage) } set { objc_setAssociatedObject(self, "drawingPage", newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } var cropOffsetX: CGFloat { get { return objc_getAssociatedObject(self, "cropOffsetX") as! CGFloat } set { objc_setAssociatedObject(self, "cropOffsetX", newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN) } } var cropOffsetY: CGFloat { get { return objc_getAssociatedObject(self, "cropOffsetY") as! CGFloat } set { objc_setAssociatedObject(self, "cropOffsetY", newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN) } } var isChangePageSize: Bool { get { return objc_getAssociatedObject(self, "isChangePageSize") as! Bool } set { objc_setAssociatedObject(self, "isChangePageSize", newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN) } } var cropRect: NSRect { get { return objc_getAssociatedObject(self, "cropRect") as! NSRect } set { objc_setAssociatedObject(self, "cropRect", newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN) } } } class KMCropInfo: NSObject { var drawPage: CPDFPage! var cropOffsetX: CGFloat = 0 var cropOffsetY: CGFloat = 0 var isChangePageSize: Bool = false var cropRect: NSRect! } class KMCropPDFView: CPDFView { var drawInfo: Array = [] override func draw(_ page: CPDFPage!, to context: CGContext!) { super.draw(page, to: context) if (self.drawInfo.count > 0) { drawCropPage(page, to: context) } } private func drawCropPage(_ cropPage: CPDFPage, to context: CGContext!) { // let myPage: KMCropPDFPage = cropPage as! KMCropPDFPage let info: KMCropInfo = self.drawInfo[Int(self.document.index(for: cropPage))] if (info.drawPage != nil) { let originalRect = cropPage.bounds(for: .mediaBox) let drawPage = info.drawPage let cropRect = drawPage!.bounds(for: .mediaBox) /// 原始page的宽度(不管有没有旋转,都是旋转度数等于0) let orgPageWidth: CGFloat = NSWidth(cropRect) /// 原始page的高度 let orgPageHeight: CGFloat = NSHeight(cropRect) let spaceX = info.cropOffsetX let spaceY = info.cropOffsetY let scale: CGFloat = min(NSWidth(originalRect)/orgPageWidth, NSHeight(originalRect)/orgPageHeight) NSGraphicsContext.saveGraphicsState() context.translateBy(x: spaceX,y: spaceY) context.scaleBy(x: scale, y: scale) if #available(macOS 10.12, *) { drawPage?.draw(with: .cropBox, to: context) drawPage?.transform(context, for: .cropBox) } else { NSGraphicsContext.saveGraphicsState() NSGraphicsContext.current = NSGraphicsContext(cgContext: context, flipped: false) drawPage?.draw(with: .cropBox, to: context) drawPage?.transform(context, for: .cropBox) } if (info.isChangePageSize) { let tCropRect: NSRect = cropPage.cropRect let w1: CGFloat = orgPageWidth-(tCropRect.size.width)-(tCropRect.origin.x) context.setFillColor(red: 0, green: 0, blue: 0, alpha: 0.3) let rect1: NSRect = NSMakeRect(0, 0, orgPageWidth, (tCropRect.origin.y)) let rect2: NSRect = NSMakeRect(0, (tCropRect.origin.y)+(tCropRect.size.height), orgPageWidth, orgPageHeight - tCropRect.origin.y-tCropRect.size.height) let rect3: NSRect = NSMakeRect(0, tCropRect.origin.y,tCropRect.origin.x,tCropRect.size.height); var rect4Y = w1 if (w1 > 0) { rect4Y = 0 } let rect4: NSRect = NSMakeRect(tCropRect.origin.x+tCropRect.size.width, tCropRect.origin.y,rect4Y,tCropRect.size.height) context.fill(rect1) context.fill(rect2) context.fill(rect3) context.fill(rect4) } NSGraphicsContext.restoreGraphicsState() } } } class KMCropPDFPage: CPDFPage { // var drawingPage: CPDFPage! // var cropOffsetX: CGFloat = 0 // var cropOffsetY: CGFloat = 0 // var isChangePageSize: Bool = false // var cropRect: NSRect! override func draw(with box: CPDFDisplayBox, to context: CGContext!) { super.draw(with: box, to: context) let pageSize: NSSize = self.bounds(for: .mediaBox).size drawPage(with: context, page: self.cropDrawingPage!, pageSize: pageSize) } private func drawPage(with context: CGContext, page: CPDFPage, pageSize: NSSize) { let myPage: KMCropPDFPage = page as! KMCropPDFPage var originalSize: NSSize = page.bounds(for: .mediaBox).size //如果page的旋转角度为90,或者270,宽高交换 if (page.rotation % 180 != 0) { originalSize = NSMakeSize(originalSize.height, originalSize.width) } context.saveGState() context.translateBy(x: myPage.cropOffsetX, y: myPage.cropOffsetY) if #available(macOS 10.12, *) { page.draw(with: .cropBox, to: context) page.transform(context, for: .cropBox) } else { NSGraphicsContext.saveGraphicsState() NSGraphicsContext.current = NSGraphicsContext(cgContext: context, flipped: true) page.draw(with: .cropBox, to: context) NSGraphicsContext.restoreGraphicsState() page.transform(context, for: .cropBox) } context.restoreGState() } } class KMCropPreviewController: KMWatermarkAdjectivePreViewBaseController { // var testPreView: PDFView! var tipView = KMCropTipView() var windowController: KMCropSettingWindowController! override func viewDidLoad() { super.viewDidLoad() let itemTitles = [["裁剪"]] var itemModels: Array> = [] for items in itemTitles { var array: Array = [] for title in items { let model = KMWatermarkAdjectiveTopBarItemModel() model.iconName = "" model.itemTitle = title array.append(model) } itemModels.append(array) } self.topBarView.initItemData(itemArrays: itemModels) let preView: CPDFListView = CPDFListView() self.preView = preView self.preView.frame = self.preViewBox.contentView!.bounds self.preView.autoresizingMask = NSView.AutoresizingMask(rawValue: 18) self.preViewBox.contentView?.addSubview(self.preView) self.preView.autoScales = true self.preView.displaysAsBook = true self.preView.delegate = self let myPreView: CPDFListView = self.preView as! CPDFListView myPreView.pdfListViewDelegate = self // NotificationCenter.default.addObserver(self, selector: #selector(preViewSelectionDidChange), name: NSNotification.Name.CPDFViewSelectionChanged, object: nil) // self.testPreView = PDFView() // self.testPreView.frame = self.preViewBox.contentView!.bounds // self.testPreView.autoresizingMask = NSView.AutoresizingMask(rawValue: 18) // self.preViewBox.contentView?.addSubview(self.testPreView) self.topBarView.isCanApply(can: false) self.tipView.frame = self.tipBox.contentView!.frame self.tipView.autoresizingMask = NSView.AutoresizingMask(rawValue: 18) self.tipBox.addSubview(self.tipView) self.tipBox.isHidden = true self.tipView.enterAction = { () in let myPreView: CPDFListView = self.preView as! CPDFListView var rect = NSIntegralRect(myPreView.currentSelectionRect()) if (NSIsEmptyRect(rect)) { return } let window = KMCropSettingWindowController(windowNibName: "KMCropSettingWindowController") self.view.window?.beginSheet(window.window!) self.windowController = window window.itemClick = { [self] (index: Int) in if (index == 1) { /// 取消 self.view.window?.endSheet((self.windowController?.window)!) self.windowController = nil return } let pageRangeType = self.windowController.pageRangeIndex let pageCount: Int = Int(self.preView.document.pageCount) var pages: Array = [] if (pageRangeType == 0) { /// 当前页面 pages.append(self.preView.currentPageIndex) } else if (pageRangeType == 1) { /// 全部页面 for i in 0 ..< pageCount { pages.append(i) } } else if (pageRangeType == 2) { /// 奇数页面 var string: String = "" for i in 0 ..< pageCount { if (i % 2 == 1) { continue } pages.append(i) } } else if (pageRangeType == 3) { /// 偶数页面 var string: String = "" for i in 0 ..< pageCount { if (i % 2 == 0) { continue } pages.append(i) } } else { /// 自定义 for i in self.windowController.pageRangePages { pages.append(i) } } if (pages.count < 0) { let alert = NSAlert() alert.messageText = "请选择页面" alert.runModal() return } var pageSize: NSSize = NSZeroSize if (self.windowController.pageSize == "None") { } else { pageSize = KMCropTools.getPageSizeValue(self.windowController.pageSize) } for i in pages { let myPreView: CPDFListView = self.preView as! CPDFListView var page: CPDFPage = self.preView.document.page(at: UInt(i)) var rect = NSIntegralRect(myPreView.selectionRect) if (NSIsEmptyRect(rect)) { rect = getPageForegroundBox(page) } var newRect = NSIntersectionRect(rect, (page.bounds(for: .mediaBox))) page.setBounds(newRect, for: .cropBox) if (pageSize.width == 0 && pageSize.height == 0) { } else { let tiffData = page.pdfListViewTIFFData(for: rect) let index: UInt = (page.pageIndex()) // let newPage: CPDFPage = CPDFPage(image: NSImage(data: tiffData!)) self.preView.document.removePage(at: index) // newPage.setBounds(NSMakeRect(0, 0, pageSize.width, pageSize.height), for: .cropBox) // let result = self.preView.document.insertPageObject(newPage, at: index) let result = self.preView.document.insertPage(pageSize, at: index) } } /// 保存到临时路径 let toPath: String = self.preView.document.documentURL.path let documentPath = NSTemporaryDirectory() let tempPath: String = "\(documentPath)/\(toPath.lastPathComponent)" if (FileManager.default.fileExists(atPath: tempPath)) { try?FileManager.default.removeItem(atPath: tempPath) } let result = self.preView.document.write(to: URL(fileURLWithPath: tempPath)) if (result) { if (FileManager.default.fileExists(atPath: toPath)) { try?FileManager.default.removeItem(atPath: toPath) } try?FileManager.default.moveItem(atPath: tempPath, toPath: toPath) } else { try?FileManager.default.removeItem(atPath: tempPath) } DispatchQueue.main.async { let myPreView: CPDFListView = self.preView as! CPDFListView myPreView.toolMode = .textToolMode /// 刷新预览视图 self.preView.layoutDocumentView() self.preView.displayBox = .cropBox } /// 裁剪 self.view.window?.endSheet((self.windowController?.window)!) self.windowController = nil // self.cropCurrentPage(in: NSZeroSize) let count: Int = Int(self.preView.document!.pageCount) // let PDFView = KMCropPDFView() // PDFView.frame = self.preView.bounds // self.preView.superview?.addSubview(PDFView) // PDFView.document = CPDFDocument(url: self.preView.document.documentURL) // for i in 0 ..< count { // let page: KMCropPDFPage = KMCropPDFPage() // page.setBounds(NSMakeRect(0, 0, 200, 200), for: .mediaBox) // let cropPage = self.preView.document.page(at: UInt(i)) // page.cropDrawingPage = cropPage //// self.preView.document.insertPageObject(page, at: UInt(i)) //// self.preView.document.removePage(at: UInt(i)) // let currentPage = page.cropDrawingPage // let drawInfo = KMCropInfo() // drawInfo.drawPage = cropPage // PDFView.drawInfo.append(drawInfo) // PDFView.document.insertPageObject(page, at: UInt(i)) // } /// 保存到临时路径 // let toPath: String = self.preView.document.documentURL.lastPathComponent // let documentPath = NSTemporaryDirectory() // let tempPath: String = "\(documentPath)/\(toPath)" // if (FileManager.default.fileExists(atPath: tempPath)) { // try?FileManager.default.removeItem(atPath: tempPath) // } // // let result = PDFView.document.write(to: URL(fileURLWithPath: tempPath)) // // DispatchQueue.main.async { // let myPreView: CPDFListView = self.preView as! CPDFListView // myPreView.toolMode = .textToolMode // // self.preView.layoutDocumentView() // } } } } // @objc func preViewSelectionDidChange(sender: NSNotification) { // if (self.preView.isEqual(to: sender.object)) { //// self.preView.currentSelection // print("1111111111") // //// NSUInteger eventMask = NSEventMaskLeftMouseUp | NSEventMaskLeftMouseDragged; //// let theEvent = [self.view.window.nextEventMatchingMask:NSEventMaskLeftMouseUp]; //// let theEvent = self.view.window?.nextEvent(matching: .leftMouseUp.union(.rightMouseUp).union(.otherMouseUp)) //// if (theEvent?.type == .leftMouseUp) { // let myPreview: CPDFListView = self.preView as! CPDFListView // if (NSIsEmptyRect(myPreview.selectionRect)) { // print("end") // } // } // } override func viewDidAppear() { super.viewDidAppear() // if (self.documentURL != nil) { // self.testPreView.document = PDFDocument(url: self.documentURL) // } } override func topItemClick(index: Int) { let menu = NSMenu() let titles = ["裁剪当前页面 - 白边距", "裁剪所有页面 - 自动", "自定义裁剪区域"] for title in titles { let item = NSMenuItem(title: title, action: #selector(itemAction), target: self) item?.tag = titles.firstIndex(of: title)! menu.addItem(item!) } menu.popUp(positioning: nil, at: NSPoint(x: self.topBarView.frame.midX-100, y: 0), in: self.topBarView) } @objc private func itemAction(sender: NSMenuItem) { if (sender.tag == 0) { /// 裁剪当前页面 - 白边距 self.tipBox.isHidden = true cropCurrentPage() return } if (sender.tag == 1) { /// 裁剪所有页面 - 自动 self.tipBox.isHidden = true cropAllPate() return } //// 自定义裁剪区域 let myPreView: CPDFListView = self.preView as! CPDFListView myPreView.toolMode = .selectToolMode self.preView.autoScales = true self.preView.autoScales = false var pageHeight: CGFloat = NSHeight(self.preView.currentPage().bounds(for: self.preView.displayBox)) if (self.preView.displaysPageBreaks) { pageHeight += 8 } var scaleFactor: CGFloat = fmax(self.preView.minimumScaleFactor, NSHeight(self.preView.frame)/pageHeight) // if (scaleFactor < self.preView.scaleFactor) { self.preView.scaleFactor = scaleFactor // } self.tipBox.isHidden = false self.tipView.setString(string: "请框选裁剪区域") } private func cropCurrentPage(in pageSize: NSSize) { let myPreView: CPDFListView = self.preView as! CPDFListView var rect = NSIntegralRect(myPreView.currentSelectionRect()) var page: CPDFPage? if ((myPreView.currentSelectionPage()) != nil) { page = myPreView.currentSelectionPage() } else { page = myPreView.currentPage() } if (NSIsEmptyRect(rect)) { rect = getPageForegroundBox(page!) } let tiffData = page!.pdfListViewTIFFData(for: rect) let index: UInt = (page?.pageIndex())! var newRect = NSIntersectionRect(rect, (page?.bounds(for: .mediaBox))!) page?.setBounds(newRect, for: .cropBox) self.preView.document.removePage(at: index) // let newPage: CPDFPage = CPDFPage(image: NSImage(data: tiffData!)) // newPage.setBounds(NSMakeRect(0, 0, pageSize.width, pageSize.height), for: .cropBox) // let result = self.preView.document.insertPageObject(newPage, at: index) let result = self.preView.document.insertPage(pageSize, at: index) // var newDoc = CPDFDocument() /// 刷新预览视图 self.preView.layoutDocumentView() self.preView.displayBox = .cropBox } private func cropAllPate() { var size = NSZeroSize for i in 0 ..< self.preView.document.pageCount { let page = self.preView.document.page(at: i) var rect = getPageForegroundBox(page!) size.width = fmax(size.width, NSWidth(rect)) size.height = fmax(size.height, NSHeight(rect)) } var rectArray: Array = [] for i in 0 ..< self.preView.document.pageCount { let page = self.preView.document.page(at: i) var rect = getPageForegroundBox(page!) var bounds: NSRect = (page?.bounds(for: .mediaBox))! if (rect.minX - bounds.minX > bounds.maxX-rect.maxX) { rect.origin.x = rect.maxX-size.width } rect.origin.y = rect.maxY-size.height rect.size = size if (NSWidth(rect) > NSWidth(bounds)) { rect.size.width = NSWidth(bounds) } if (NSHeight(rect) > NSHeight(bounds)) { rect.size.height = NSHeight(bounds) } if (NSMinX(rect) < NSMinX(bounds)) { rect.origin.x = NSMinX(bounds) } else if (NSMaxX(rect) > NSMaxX(bounds)) { rect.origin.x = NSMaxX(bounds) - NSWidth(rect) } if (NSMinY(rect) < NSMinY(bounds)) { rect.origin.y = NSMinY(bounds) } else if (NSMaxY(rect) > NSMaxY(bounds)) { rect.origin.y = NSMaxY(bounds) - NSHeight(rect) } rectArray.append(rect) } cropPages(to: rectArray) } private func cropPages(to rects: Array) { let currentPage = self.preView.currentPage() let visibleRect: NSRect = self.preView.convert(self.preView.convert(self.preView.documentView().visibleRect, from: self.preView.documentView()), to: self.preView.currentPage()) var oldRectArray: Array = [] for i in 0 ..< self.preView.document.pageCount { let page = self.preView.document.page(at: i) var rect = NSIntersectionRect(rects[Int(i)], (page?.bounds(for: .mediaBox))!) let oldRect = page?.bounds(for: .cropBox) oldRectArray.append(oldRect!) page?.setBounds(rect, for: .cropBox) } /// 刷新预览视图 self.preView.layoutDocumentView() self.preView.displayBox = .cropBox self.preView.go(to: currentPage) self.preView.go(to: visibleRect, on: currentPage) } private func cropCurrentPage() { let myPreView: CPDFListView = self.preView as! CPDFListView var rect = NSIntegralRect(myPreView.currentSelectionRect()) var page: CPDFPage? if ((myPreView.currentSelectionPage()) != nil) { page = myPreView.currentSelectionPage() } else { page = myPreView.currentPage() } if (NSIsEmptyRect(rect)) { rect = getPageForegroundBox(page!) } let index: UInt = (page?.pageIndex())! cropPage(at: index, in: rect) } func cropPage(at index: UInt, in rect: NSRect) { let oldRect = self.preView.document.page(at: index)?.bounds(for: .cropBox) /// undo \ redo 处理 // NSUndoManager *undoManager = [[self document] undoManager]; // let undoManager = UndoManager() // (undoManager.prepare(withInvocationTarget: self) as! KMCropPreviewController).cropPage(at: index, in: oldRect!) // undoManager.setActionName(NSLocalizedString("Crop Page", comment: "Undo action name")) // [[self document] undoableActionIsDiscardable]; var page = self.preView.document.page(at: index) var newRect = NSIntersectionRect(rect, (page?.bounds(for: .mediaBox))!) page?.setBounds(newRect, for: .cropBox) /// 刷新预览视图 self.preView.layoutDocumentView() self.preView.displayBox = .cropBox } private func getPageForegroundBox(_ page: CPDFPage) -> NSRect { let marginWidth: CGFloat = 10 let marginHeight: CGFloat = 10 let imageRep = newBitmapImageRepForBox(page, .mediaBox) let bounds = page.bounds(for: .mediaBox) var foregroundBox = imageRep.foregroundRect() if (imageRep == nil) { foregroundBox = bounds } else if (NSIsEmptyRect(foregroundBox)) { let centerPoint = NSPoint(x: bounds.midX, y: bounds.midY) let origin = NSPoint(x: round(centerPoint.x), y: round(centerPoint.y)) foregroundBox.origin = origin foregroundBox.size = NSZeroSize } else { let origin = NSPoint(x: foregroundBox.origin.x+bounds.origin.x, y: foregroundBox.origin.y+bounds.origin.y) foregroundBox.origin = origin } return NSIntegralRect(NSInsetRect(foregroundBox, -marginWidth, -marginHeight)) } private func newBitmapImageRepForBox(_ page: CPDFPage, _ box: CPDFDisplayBox) -> NSBitmapImageRep { let bounds = page.bounds(for: box) var imageRep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(NSWidth(bounds)), pixelsHigh: Int(NSHeight(bounds)), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: .calibratedRGB, bitmapFormat: NSBitmapImageRep.Format(rawValue: 0), bytesPerRow: 0, bitsPerPixel: 32) if (imageRep != nil) { NSGraphicsContext.saveGraphicsState() NSGraphicsContext.current = NSGraphicsContext.init(bitmapImageRep: imageRep!) NSGraphicsContext.current?.imageInterpolation = .none NSGraphicsContext.current?.shouldAntialias = false if (page.rotation != 0) { var transform = NSAffineTransform() if (page.rotation == 90) { transform.translateX(by: NSWidth(bounds), yBy: 0) } else if (page.rotation == 180) { transform.translateX(by: NSHeight(bounds), yBy: NSWidth(bounds)) } else if (page.rotation == 270) { transform.translateX(by: 0, yBy: NSHeight(bounds)) } transform.rotate(byDegrees: CGFloat(page.rotation)) transform.concat() } page.draw(with: box, to: (NSGraphicsContext.current?.cgContext as! CGContext)) // page.draw(with: box) NSGraphicsContext.current?.imageInterpolation = .default NSGraphicsContext.restoreGraphicsState() } return imageRep! } } extension KMCropPreviewController: CPDFViewDelegate { func pdfViewEditingSelectionDidChanged(_ pdfView: CPDFView!) { } } extension KMCropPreviewController: CPDFListViewDelegate { func pdfListViewDidSelectionEnd(_ pdfListView: CPDFListView!) { if (self.preView.isEqual(to: pdfListView)) { self.tipView.setString(string: "请按 Enter 键确定裁剪区域") } } } //extension PDFPage { // func getPageForegroundBox() -> NSRect { // let marginWidth: CGFloat = 10 // let marginHeight: CGFloat = 10 // // let imageRep = newBitmapImageRepForBox(.mediaBox) // let bounds = bounds(for: .mediaBox) // var foregroundBox = imageRep.foregroundRect() // if (imageRep == nil) { // foregroundBox = bounds // } else if (NSIsEmptyRect(foregroundBox)) { // let centerPoint = NSPoint(x: bounds.midX, y: bounds.midY) // let origin = NSPoint(x: round(centerPoint.x), y: round(centerPoint.y)) // foregroundBox.origin = origin // foregroundBox.size = NSZeroSize // } else { // let origin = NSPoint(x: foregroundBox.origin.x+bounds.origin.x, y: foregroundBox.origin.y+bounds.origin.y) // foregroundBox.origin = origin // } // // return NSIntegralRect(NSInsetRect(foregroundBox, -marginWidth, -marginHeight)) // } // // func newBitmapImageRepForBox(_ box: PDFDisplayBox) -> NSBitmapImageRep { // let bounds = bounds(for: box) // let imageRep = NSBitmapImageRep(bitmapDataPlanes: nil, // pixelsWide: Int(NSWidth(bounds)), // pixelsHigh: Int(NSHeight(bounds)), // bitsPerSample: 8, // samplesPerPixel: 4, // hasAlpha: true, // isPlanar: false, // colorSpaceName: .calibratedRGB, // bitmapFormat: NSBitmapImageRep.Format(rawValue: 0), // bytesPerRow: 0, // bitsPerPixel: 32) // // if (imageRep != nil) { // NSGraphicsContext.saveGraphicsState() // NSGraphicsContext.current = NSGraphicsContext.init(bitmapImageRep: imageRep!) // NSGraphicsContext.current?.imageInterpolation = .none // NSGraphicsContext.current?.shouldAntialias = false // if (self.rotation != 0) { // let transform = NSAffineTransform() // if (self.rotation == 90) { // transform.translateX(by: NSWidth(bounds), yBy: 0) // } else if (self.rotation == 180) { // transform.translateX(by: NSHeight(bounds), yBy: NSWidth(bounds)) // } else if (self.rotation == 270) { // transform.translateX(by: 0, yBy: NSHeight(bounds)) // } // // transform.rotate(byDegrees: CGFloat(self.rotation)) // transform.concat() // } // // draw(with: box) // NSGraphicsContext.current?.imageInterpolation = .default // NSGraphicsContext.restoreGraphicsState() // } // // return imageRep! // } //}