diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 658374a..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml index 02c2e0c..c57c17e 100644 --- a/.github/workflows/flutter.yml +++ b/.github/workflows/flutter.yml @@ -16,14 +16,14 @@ jobs: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 # - uses: actions/setup-java@v3.11.0 # with: # java-version: 11 # distribution: temurin - uses: subosito/flutter-action@v2 with: - flutter-version: '3.10.6' + flutter-version: '3.22.0' channel: 'stable' architecture: x64 cache: true diff --git a/packages/.DS_Store b/packages/.DS_Store deleted file mode 100644 index 79397b9..0000000 Binary files a/packages/.DS_Store and /dev/null differ diff --git a/packages/apple_vision_image_depth/darwin/Classes/AppleVisionImageDepthPlugin.swift b/packages/apple_vision_image_depth/darwin/Classes/AppleVisionImageDepthPlugin.swift index 7bb9dcc..85eaa63 100644 --- a/packages/apple_vision_image_depth/darwin/Classes/AppleVisionImageDepthPlugin.swift +++ b/packages/apple_vision_image_depth/darwin/Classes/AppleVisionImageDepthPlugin.swift @@ -52,8 +52,12 @@ public class AppleVisionImageDepthPlugin: NSObject, FlutterPlugin { return result(FlutterError(code: "INVALID OS", message: "requires version 14.0", details: nil)) } #elseif os(macOS) - return result(convertImage(Data(data.data),CGSize(width: width , height: height),CIFormat.ARGB8,orientation,format)) - #endif + if #available(macOS 14.0, *) { + return result(convertImage(Data(data.data),CGSize(width: width , height: height),CIFormat.ARGB8,orientation,format)) + } else { + return result(FlutterError(code: "INVALID OS", message: "requires version 14.0", details: nil)) + } + #endif default: result(FlutterMethodNotImplemented) } @@ -62,6 +66,8 @@ public class AppleVisionImageDepthPlugin: NSObject, FlutterPlugin { // Gets called when a new image is added to the buffer #if os(iOS) @available(iOS 14.0, *) + #elseif os(macOS) + @available(macOS 14.0, *) #endif func convertImage(_ data: Data,_ imageSize: CGSize,_ format: CIFormat,_ oriString: String,_ fileType: String) -> [String:Any?]{ var event:[String:Any?] = ["name":"noData"]; @@ -115,106 +121,104 @@ public class AppleVisionImageDepthPlugin: NSObject, FlutterPlugin { } let imageRecognition = VNCoreMLRequest(model: model!, completionHandler: { (request, error) in - if let results = request.results as? [VNCoreMLFeatureValueObservation] { + if let results = request.results as? [VNPixelBufferObservation] { var depthData:[Data?] = [] for observation in results { - let depthmap = observation.featureValue.multiArrayValue + let depthmap = CIImage(cvPixelBuffer: observation.pixelBuffer) - var originalImageOr:CIImage - if originalImage == nil{ - originalImageOr = CIImage(data:data)! - } - else{ - originalImageOr = originalImage! - } + var originalImageOr:CIImage + if originalImage == nil{ + originalImageOr = CIImage(data:data)! + } + else{ + originalImageOr = originalImage! + } - if depthmap != nil{ - (min, max) = self.getMinMax(from: depthmap!) - var ciImage = CIImage(cgImage: depthmap!.cgImage(min: min,max: max)!) - - // Scale the mask image to fit the bounds of the video frame. - let scaleX = originalImageOr.extent.width / ciImage.extent.width - let scaleY = originalImageOr.extent.height / ciImage.extent.height - ciImage = ciImage.transformed(by: .init(scaleX: scaleX, y: scaleY)) + + var ciImage = depthmap + let scaleX = originalImageOr.extent.width / ciImage.extent.width + let scaleY = originalImageOr.extent.height / ciImage.extent.height + ciImage = ciImage.transformed(by: .init(scaleX: scaleX, y: scaleY)) #if os(iOS) - var uiImage:Data? - switch fileType { - case "jpg": - uiImage = UIImage(ciImage: ciImage).jpegData(compressionQuality: 1.0) - case "jpeg": - uiImage = UIImage(ciImage: ciImage).jpegData(compressionQuality: 1.0) - case "bmp": - uiImage = nil - case "png": - uiImage = UIImage(ciImage: ciImage).pngData() - case "tiff": - uiImage = nil - default: + var uiImage:Data? + switch fileType { + case "jpg": + uiImage = UIImage(ciImage: ciImage).jpegData(compressionQuality: 1.0) + case "jpeg": + uiImage = UIImage(ciImage: ciImage).jpegData(compressionQuality: 1.0) + case "bmp": uiImage = nil + case "png": + uiImage = UIImage(ciImage: ciImage).pngData() + case "tiff": + uiImage = nil + default: + uiImage = nil + } + + if uiImage == nil{ + let ciContext = CIContext() + let rowBytes = 4 * Int(ciImage.extent.width) // 4 channels (RGBA) of 8-bit data + let dataSize = rowBytes * Int(ciImage.extent.height) + var data = Data(count: dataSize) + data.withUnsafeMutableBytes { data in + ciContext.render(ciImage, toBitmap: data, rowBytes: rowBytes, bounds: ciImage.extent, format: .RGBA8, colorSpace: CGColorSpace(name: CGColorSpace.sRGB)!) } - - if uiImage == nil{ - let ciContext = CIContext() - let rowBytes = 4 * Int(ciImage.extent.width) // 4 channels (RGBA) of 8-bit data - let dataSize = rowBytes * Int(ciImage.extent.height) - var data = Data(count: dataSize) - data.withUnsafeMutableBytes { data in - ciContext.render(ciImage, toBitmap: data, rowBytes: rowBytes, bounds: ciImage.extent, format: .RGBA8, colorSpace: CGColorSpace(name: CGColorSpace.sRGB)!) - } - if fileType == "bmp"{ - uiImage = rgba2bitmap( - data, - Int(ciImage.extent.width), - Int(ciImage.extent.height) - ) - } - else{ - uiImage = data - } - } - depthData.append(ciImage?.cgImage?.dataProvider?.data as Data?) - #elseif os(macOS) - var nsImage:Data? - switch fileType { - case "jpg": - nsImage = NSBitmapImageRep(ciImage:ciImage).representation( - using: .jpeg, - properties: [:] - ) - case "jpeg": - nsImage = NSBitmapImageRep(ciImage:ciImage).representation( - using: .jpeg2000, - properties: [:] - ) - case "bmp": - nsImage = NSBitmapImageRep(ciImage:ciImage).representation( - using: .bmp, - properties: [:] - ) - case "png": - nsImage = NSBitmapImageRep(ciImage:ciImage).representation( - using: .png, - properties: [:] - ) - case "tiff": - nsImage = NSBitmapImageRep(ciImage:ciImage).representation( - using: .tiff, - properties: [:] - ) - default: - nsImage = nil + if fileType == "bmp"{ + uiImage = rgba2bitmap( + data, + Int(ciImage.extent.width), + Int(ciImage.extent.height) + ) } - if nsImage == nil{ - let u = NSBitmapImageRep(ciImage:ciImage) - let bytesPerRow = u.bytesPerRow - let height = Int(u.size.height) - - nsImage = Data(bytes: u.bitmapData!, count: Int(bytesPerRow*height)) + else{ + uiImage = data } - depthData.append(nsImage!) - #endif } + depthData.append(ciImage?.cgImage?.dataProvider?.data as Data?) + + #elseif os(macOS) + var nsImage:Data? + switch fileType { + case "jpg": + nsImage = NSBitmapImageRep(ciImage:ciImage).representation( + using: .jpeg, + properties: [:] + ) + case "jpeg": + nsImage = NSBitmapImageRep(ciImage:ciImage).representation( + using: .jpeg2000, + properties: [:] + ) + case "bmp": + nsImage = NSBitmapImageRep(ciImage:ciImage).representation( + using: .bmp, + properties: [:] + ) + case "png": + nsImage = NSBitmapImageRep(ciImage:ciImage).representation( + using: .png, + properties: [:] + ) + case "tiff": + nsImage = NSBitmapImageRep(ciImage:ciImage).representation( + using: .tiff, + properties: [:] + ) + default: + nsImage = nil + } + if nsImage == nil{ + let u = NSBitmapImageRep(ciImage:ciImage) + let bytesPerRow = u.bytesPerRow + let height = Int(u.size.height) + + nsImage = Data(bytes: u.bitmapData!, count: Int(bytesPerRow*height)) + } + depthData.append(nsImage!) + #endif + } event = [ "name": "imageDepth", @@ -226,6 +230,17 @@ public class AppleVisionImageDepthPlugin: NSObject, FlutterPlugin { "height": imageSize.height ] ] + }else{ + event = [ + "name": "imageDepth", + "data": request.results, + "max": 0, + "min":0, + "imageSize": [ + "width": 0, + "height": 0 + ] + ] } }) let requests: [VNRequest] = [imageRecognition] @@ -237,12 +252,14 @@ public class AppleVisionImageDepthPlugin: NSObject, FlutterPlugin { #if os(iOS) @available(iOS 14.0, *) + #elseif os(macOS) + @available(macOS 14.0, *) #endif static func createImageDepth() -> VNCoreMLModel { // Use a default model configuration. let defaultConfig = MLModelConfiguration() // Create an instance of the image classifier's wrapper class. - let imageDepthWrapper = try? FCRNFP16(configuration: defaultConfig) + let imageDepthWrapper = try? DepthModel(configuration: defaultConfig) guard let imageDepth = imageDepthWrapper else { fatalError("App failed to create an image classifier model instance.") } @@ -252,38 +269,7 @@ public class AppleVisionImageDepthPlugin: NSObject, FlutterPlugin { guard let imageDepthVisionModel = try? VNCoreMLModel(for: imageDepthModel) else { fatalError("App failed to create a `VNCoreMLModel` instance.") } - return imageDepthVisionModel - } - func getMinMax(from heatmaps: MLMultiArray) -> (Double, Double) { - guard heatmaps.shape.count >= 3 else { - print("heatmap's shape is invalid. \(heatmaps.shape)") - return (0, 0) - } - let _/*keypoint_number*/ = heatmaps.shape[0].intValue - let heatmap_w = heatmaps.shape[1].intValue - let heatmap_h = heatmaps.shape[2].intValue - - var convertedHeatmap: Array> = Array(repeating: Array(repeating: 0.0, count: heatmap_w), count: heatmap_h) - - var minimumValue: Double = Double.greatestFiniteMagnitude - var maximumValue: Double = -Double.greatestFiniteMagnitude - for i in 0.. 0 else { continue } - convertedHeatmap[j][i] = confidence - - if minimumValue > confidence { - minimumValue = confidence - } - if maximumValue < confidence { - maximumValue = confidence - } - } - } - - return (minimumValue,maximumValue) + return imageDepthVisionModel } } diff --git a/packages/apple_vision_image_depth/darwin/Classes/DepthAnythingV2SmallF16.mlpackage/Data/com.apple.CoreML/DepthModel.mlmodel b/packages/apple_vision_image_depth/darwin/Classes/DepthAnythingV2SmallF16.mlpackage/Data/com.apple.CoreML/DepthModel.mlmodel new file mode 100644 index 0000000..402f77d Binary files /dev/null and b/packages/apple_vision_image_depth/darwin/Classes/DepthAnythingV2SmallF16.mlpackage/Data/com.apple.CoreML/DepthModel.mlmodel differ diff --git a/packages/apple_vision_image_depth/darwin/Classes/DepthAnythingV2SmallF16.mlpackage/Data/com.apple.CoreML/weights/weight.bin b/packages/apple_vision_image_depth/darwin/Classes/DepthAnythingV2SmallF16.mlpackage/Data/com.apple.CoreML/weights/weight.bin new file mode 100644 index 0000000..97eccab Binary files /dev/null and b/packages/apple_vision_image_depth/darwin/Classes/DepthAnythingV2SmallF16.mlpackage/Data/com.apple.CoreML/weights/weight.bin differ diff --git a/packages/apple_vision_image_depth/darwin/Classes/DepthAnythingV2SmallF16.mlpackage/Manifest.json b/packages/apple_vision_image_depth/darwin/Classes/DepthAnythingV2SmallF16.mlpackage/Manifest.json new file mode 100644 index 0000000..5477cfb --- /dev/null +++ b/packages/apple_vision_image_depth/darwin/Classes/DepthAnythingV2SmallF16.mlpackage/Manifest.json @@ -0,0 +1,18 @@ +{ + "fileFormatVersion": "1.0.0", + "itemInfoEntries": { + "20D05BA4-5503-4673-8F11-11EF6A25EE9D": { + "author": "com.apple.CoreML", + "description": "CoreML Model Weights", + "name": "weights", + "path": "com.apple.CoreML/weights" + }, + "D698F85A-E9D9-47BF-8C1B-5A441F139CAA": { + "author": "com.apple.CoreML", + "description": "CoreML Model Specification", + "name": "DepthModel.mlmodel", + "path": "com.apple.CoreML/DepthModel.mlmodel" + } + }, + "rootModelIdentifier": "D698F85A-E9D9-47BF-8C1B-5A441F139CAA" +} diff --git a/packages/apple_vision_image_depth/darwin/Classes/image.swift b/packages/apple_vision_image_depth/darwin/Classes/image.swift deleted file mode 100644 index 1dbc746..0000000 --- a/packages/apple_vision_image_depth/darwin/Classes/image.swift +++ /dev/null @@ -1,417 +0,0 @@ -/* - Copyright (c) 2017-2020 M.I. Hollemans - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -import Accelerate -import CoreML - -public protocol MultiArrayType: Comparable { - static var multiArrayDataType: MLMultiArrayDataType { get } - static func +(lhs: Self, rhs: Self) -> Self - static func -(lhs: Self, rhs: Self) -> Self - static func *(lhs: Self, rhs: Self) -> Self - static func /(lhs: Self, rhs: Self) -> Self - init(_: Int) - var toUInt8: UInt8 { get } -} - -extension Double: MultiArrayType { - public static var multiArrayDataType: MLMultiArrayDataType { return .double } - public var toUInt8: UInt8 { return UInt8(self) } -} - -extension Float: MultiArrayType { - public static var multiArrayDataType: MLMultiArrayDataType { return .float32 } - public var toUInt8: UInt8 { return UInt8(self) } -} - -extension Int32: MultiArrayType { - public static var multiArrayDataType: MLMultiArrayDataType { return .int32 } - public var toUInt8: UInt8 { return UInt8(self) } -} - -extension MLMultiArray { - /** - Converts the multi-array to a CGImage. - - The multi-array must have at least 2 dimensions for a grayscale image, or - at least 3 dimensions for a color image. - - The default expected shape is (height, width) or (channels, height, width). - However, you can change this using the `axes` parameter. For example, if - the array shape is (1, height, width, channels), use `axes: (3, 1, 2)`. - - If `channel` is not nil, only converts that channel to a grayscale image. - This lets you visualize individual channels from a multi-array with more - than 4 channels. - - Otherwise, converts all channels. In this case, the number of channels in - the multi-array must be 1 for grayscale, 3 for RGB, or 4 for RGBA. - - Use the `min` and `max` parameters to put the values from the array into - the range [0, 255], if not already: - - - `min`: should be the smallest value in the data; this will be mapped to 0. - - `max`: should be the largest value in the data; will be mapped to 255. - - For example, if the range of the data in the multi-array is [-1, 1], use - `min: -1, max: 1`. If the range is already [0, 255], then use the defaults. - */ - public func cgImage(min: Double = 0, - max: Double = 255, - channel: Int? = nil, - axes: (Int, Int, Int)? = nil) -> CGImage? { - switch self.dataType { - case .double: - return _image(min: min, max: max, channel: channel, axes: axes) - case .float32: - return _image(min: Float(min), max: Float(max), channel: channel, axes: axes) - case .int32: - return _image(min: Int32(min), max: Int32(max), channel: channel, axes: axes) - @unknown default: - fatalError("Unsupported data type \(dataType.rawValue)") - } - } - - /** - Helper function that allows us to use generics. The type of `min` and `max` - is also the dataType of the MLMultiArray. - */ - private func _image(min: T, - max: T, - channel: Int?, - axes: (Int, Int, Int)?) -> CGImage? { - if let (b, w, h, c) = toRawBytes(min: min, max: max, channel: channel, axes: axes) { - if c == 1 { - return CGImage.fromByteArrayGray(b, width: w, height: h) - } else { - return CGImage.fromByteArrayRGBA(b, width: w, height: h) - } - } - return nil - } - - /** - Converts the multi-array into an array of RGBA or grayscale pixels. - - - Note: This is not particularly fast, but it is flexible. You can change - the loops to convert the multi-array whichever way you please. - - - Note: The type of `min` and `max` must match the dataType of the - MLMultiArray object. - - - Returns: tuple containing the RGBA bytes, the dimensions of the image, - and the number of channels in the image (1, 3, or 4). - */ - public func toRawBytes(min: T, - max: T, - channel: Int? = nil, - axes: (Int, Int, Int)? = nil) - -> (bytes: [UInt8], width: Int, height: Int, channels: Int)? { - // MLMultiArray with unsupported shape? - if shape.count < 2 { - print("Cannot convert MLMultiArray of shape \(shape) to image") - return nil - } - - // Figure out which dimensions to use for the channels, height, and width. - let channelAxis: Int - let heightAxis: Int - let widthAxis: Int - if let axes = axes { - channelAxis = axes.0 - heightAxis = axes.1 - widthAxis = axes.2 - guard channelAxis >= 0 && channelAxis < shape.count && - heightAxis >= 0 && heightAxis < shape.count && - widthAxis >= 0 && widthAxis < shape.count else { - print("Invalid axes \(axes) for shape \(shape)") - return nil - } - } else if shape.count == 2 { - // Expected shape for grayscale is (height, width) - heightAxis = 0 - widthAxis = 1 - channelAxis = -1 // Never be used - } else { - // Expected shape for color is (channels, height, width) - channelAxis = 0 - heightAxis = 1 - widthAxis = 2 - } - - let height = self.shape[heightAxis].intValue - let width = self.shape[widthAxis].intValue - let yStride = self.strides[heightAxis].intValue - let xStride = self.strides[widthAxis].intValue - - let channels: Int - let cStride: Int - let bytesPerPixel: Int - let channelOffset: Int - - // MLMultiArray with just two dimensions is always grayscale. (We ignore - // the value of channelAxis here.) - if shape.count == 2 { - channels = 1 - cStride = 0 - bytesPerPixel = 1 - channelOffset = 0 - - // MLMultiArray with more than two dimensions can be color or grayscale. - } else { - let channelDim = self.shape[channelAxis].intValue - if let channel = channel { - if channel < 0 || channel >= channelDim { - print("Channel must be -1, or between 0 and \(channelDim - 1)") - return nil - } - channels = 1 - bytesPerPixel = 1 - channelOffset = channel - } else if channelDim == 1 { - channels = 1 - bytesPerPixel = 1 - channelOffset = 0 - } else { - if channelDim != 3 && channelDim != 4 { - print("Expected channel dimension to have 1, 3, or 4 channels, got \(channelDim)") - return nil - } - channels = channelDim - bytesPerPixel = 4 - channelOffset = 0 - } - cStride = self.strides[channelAxis].intValue - } - - // Allocate storage for the RGBA or grayscale pixels. Set everything to - // 255 so that alpha channel is filled in if only 3 channels. - let count = height * width * bytesPerPixel - var pixels = [UInt8](repeating: 255, count: count) - - // Grab the pointer to MLMultiArray's memory. - var ptr = UnsafeMutablePointer(OpaquePointer(self.dataPointer)) - ptr = ptr.advanced(by: channelOffset * cStride) - - // Loop through all the pixels and all the channels and copy them over. - for c in 0..(_ x: T, min: T, max: T) -> T { - if x < min { return min } - if x > max { return max } - return x -} - - -/** - Fast conversion from MLMultiArray to CGImage using the vImage framework. - - - Parameters: - - features: A multi-array with data type FLOAT32 and three dimensions - (3, height, width). - - min: The smallest value in the multi-array. This value, as well as any - smaller values, will be mapped to 0 in the output image. - - max: The largest value in the multi-array. This and any larger values - will be will be mapped to 255 in the output image. - - - Returns: a new CGImage or nil if the conversion fails -*/ -public func createCGImage(fromFloatArray features: MLMultiArray, - min: Float = 0, - max: Float = 255) -> CGImage? { - assert(features.dataType == .float32) - assert(features.shape.count == 3) - - let ptr = UnsafeMutablePointer(OpaquePointer(features.dataPointer)) - - let height = features.shape[1].intValue - let width = features.shape[2].intValue - let channelStride = features.strides[0].intValue - let rowStride = features.strides[1].intValue - let srcRowBytes = rowStride * MemoryLayout.stride - - var blueBuffer = vImage_Buffer(data: ptr, - height: vImagePixelCount(height), - width: vImagePixelCount(width), - rowBytes: srcRowBytes) - var greenBuffer = vImage_Buffer(data: ptr.advanced(by: channelStride), - height: vImagePixelCount(height), - width: vImagePixelCount(width), - rowBytes: srcRowBytes) - var redBuffer = vImage_Buffer(data: ptr.advanced(by: channelStride * 2), - height: vImagePixelCount(height), - width: vImagePixelCount(width), - rowBytes: srcRowBytes) - - let destRowBytes = width * 4 - - var error: vImage_Error = 0 - var pixels = [UInt8](repeating: 0, count: height * destRowBytes) - - pixels.withUnsafeMutableBufferPointer { ptr in - var destBuffer = vImage_Buffer(data: ptr.baseAddress!, - height: vImagePixelCount(height), - width: vImagePixelCount(width), - rowBytes: destRowBytes) - - error = vImageConvert_PlanarFToBGRX8888(&blueBuffer, - &greenBuffer, - &redBuffer, - Pixel_8(255), - &destBuffer, - [max, max, max], - [min, min, min], - vImage_Flags(0)) - } - - if error == kvImageNoError { - return CGImage.fromByteArrayRGBA(pixels, width: width, height: height) - } else { - return nil - } -} - -#if canImport(UIKit) - -import UIKit - -extension MLMultiArray { - public func image(min: Double = 0, - max: Double = 255, - channel: Int? = nil, - axes: (Int, Int, Int)? = nil) -> UIImage? { - let cgImg = cgImage(min: min, max: max, channel: channel, axes: axes) - return cgImg.map { UIImage(cgImage: $0) } - } -} - -public func createUIImage(fromFloatArray features: MLMultiArray, - min: Float = 0, - max: Float = 255) -> UIImage? { - let cgImg = createCGImage(fromFloatArray: features, min: min, max: max) - return cgImg.map { UIImage(cgImage: $0) } -} - -#endif - -/* - Copyright (c) 2017-2019 M.I. Hollemans - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -import CoreGraphics - -extension CGImage { - /** - Converts the image into an array of RGBA bytes. - */ - @nonobjc public func toByteArrayRGBA() -> [UInt8] { - var bytes = [UInt8](repeating: 0, count: width * height * 4) - bytes.withUnsafeMutableBytes { ptr in - if let colorSpace = colorSpace, - let context = CGContext( - data: ptr.baseAddress, - width: width, - height: height, - bitsPerComponent: bitsPerComponent, - bytesPerRow: bytesPerRow, - space: colorSpace, - bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) { - let rect = CGRect(x: 0, y: 0, width: width, height: height) - context.draw(self, in: rect) - } - } - return bytes - } - - /** - Creates a new CGImage from an array of RGBA bytes. - */ - @nonobjc public class func fromByteArrayRGBA(_ bytes: [UInt8], - width: Int, - height: Int) -> CGImage? { - return fromByteArray(bytes, width: width, height: height, - bytesPerRow: width * 4, - colorSpace: CGColorSpaceCreateDeviceRGB(), - alphaInfo: .premultipliedLast) - } - - /** - Creates a new CGImage from an array of grayscale bytes. - */ - @nonobjc public class func fromByteArrayGray(_ bytes: [UInt8], - width: Int, - height: Int) -> CGImage? { - return fromByteArray(bytes, width: width, height: height, - bytesPerRow: width, - colorSpace: CGColorSpaceCreateDeviceGray(), - alphaInfo: .none) - } - - @nonobjc class func fromByteArray(_ bytes: [UInt8], - width: Int, - height: Int, - bytesPerRow: Int, - colorSpace: CGColorSpace, - alphaInfo: CGImageAlphaInfo) -> CGImage? { - return bytes.withUnsafeBytes { ptr in - let context = CGContext(data: UnsafeMutableRawPointer(mutating: ptr.baseAddress!), - width: width, - height: height, - bitsPerComponent: 8, - bytesPerRow: bytesPerRow, - space: colorSpace, - bitmapInfo: alphaInfo.rawValue) - return context?.makeImage() - } - } -} diff --git a/packages/apple_vision_image_depth/example/.metadata b/packages/apple_vision_image_depth/example/.metadata deleted file mode 100644 index 8629a4e..0000000 --- a/packages/apple_vision_image_depth/example/.metadata +++ /dev/null @@ -1,45 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: "abb292a07e20d696c4568099f918f6c5f330e6b0" - channel: "stable" - -project_type: app - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - - platform: android - create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - - platform: ios - create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - - platform: linux - create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - - platform: macos - create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - - platform: web - create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - - platform: windows - create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/packages/apple_vision_image_depth/example/analysis_options.yaml b/packages/apple_vision_image_depth/example/analysis_options.yaml deleted file mode 100644 index 61b6c4d..0000000 --- a/packages/apple_vision_image_depth/example/analysis_options.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# This file configures the analyzer, which statically analyzes Dart code to -# check for errors, warnings, and lints. -# -# The issues identified by the analyzer are surfaced in the UI of Dart-enabled -# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be -# invoked from the command line by running `flutter analyze`. - -# The following line activates a set of recommended lints for Flutter apps, -# packages, and plugins designed to encourage good coding practices. -include: package:flutter_lints/flutter.yaml - -linter: - # The lint rules applied to this project can be customized in the - # section below to disable rules from the `package:flutter_lints/flutter.yaml` - # included above or to enable additional rules. A list of all available lints - # and their documentation is published at - # https://dart-lang.github.io/linter/lints/index.html. - # - # Instead of disabling a lint rule for the entire project in the - # section below, it can also be suppressed for a single line of code - # or a specific dart file by using the `// ignore: name_of_lint` and - # `// ignore_for_file: name_of_lint` syntax on the line or in the file - # producing the lint. - rules: - # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options