Code Monkey home page Code Monkey logo

imageioswift's Introduction

ImageIO.Swift

CI Status Version License Platform

ImageIO.Swift makes working with images on Apple platforms easy. It's SDWebImage, FLAnimatedImage and Concorde all in one!

  • Download images asychronously.
  • Animate GIFs, PNGs and (in iOS 13) HEICs!
  • Incrementally load interlaced and progressive JPEGs.
  • Generate thumbnails directly from the file (especially useful for HEIC images because they often embed pre-rendered thumbnails).
  • Examine image details and exif metadata.

Usage

UIKit (ImageIOUIKit)

ImageSourceView handles loading and displaying images.

// display an image downloaded from a URL
let view = ImageSourceView()
view.isAnimationEnabled = true
view.load(url)

If an image url is shown in multiple places on the same screen (like a single users profile picture on a news feed layout) it will only be downloaded and loaded into memory once. It will also be intelligently cached so that subsequent requests will re-use memory and downloaded data.

You can also set an image source directly:

let view = ImageSourceView()
view.isAnimationEnabled = true
view.imageSource = imageSource

You can access the views imageSource (regardless of whether you set it directly or loaded it from a url) and subscribe to it's didUpdateData notification to track it's download. To get updates for different animation frames, you can either subclass ImageSourceView or use KVO with displayedImage.

The UIKit module also includes extensions on ImageSource to access UIImages that are correctly orriented (a feature that CGImage doesn't account for).

Experimental: SwiftUI (ImageIOSwiftUI)

Works with iOS, macOS, watchOS and tvOS!

URLImageSourceView works a lot like an img tag in html.

// display an image downloaded from a URL
URLImageSourceView(
	url: url, 
	isAnimationEnabled: true,
	label: Text("Alt text")
)

If an image url is shown in multiple places on the same screen (like a single user's profile picture on a news feed layout) it will only be downloaded and loaded into memory once. It will also be intelligently cached so that subsequent requests will re-use memory and downloaded data.

If you want to load an image source separately, you can use ImageSourceView:

// display an image source, animating if possible
ImageSourceView(
	imageSource: imageSource,
	isAnimationEnabled: true,
	label: Text("Alt text")
)

Finally, if you want to customize how an image is rendered, you can provide your own content to either URLImageSourceView or ImageSourceView:

// places an animation progress bar at the bottom of the image
URLImageSourceView(
	url: url,
	isAnimationEnabled: true,
	label: Text("Alt text")
) { imageSource, animationFrame, label in
	StaticImageSourceView(imageSource: imageSource, animationFrame: animationFrame, label: label)
		.aspectRatio(contentMode: .fit)
		.overlay(
			Rectangle()
				.fill(Color.blue.opacity(0.5))
				.frame(height: 10)
				.relativeWidth(Length(imageSource.progress(atFrame: animationFrame))),
			alignment: .bottomLeading
		)
}

The content callback is called every time image data is updated or an animation frame changes. By default, StaticImageSourceView is used to display an image frame, and you can use it as a base for your customization.

If you want to provide a placeholder while the image loads, the recommended way to do that is with a ZStack:

// load an image, clipped by a circle with a gray background and placeholder image
ZStack {
	Image(systemName: "person.fill")
		.foregroundColor(Color(white: 0.4))
	URLImageSourceView(url: user.picture.medium)
		.frame(width: 36, height: 36)
}
.frame(width: 36, height: 36)
.background(Color(white: 0.8))
.clipShape(Circle())

This way images that load incrementally will be shown as they load.

Disclaimer: I had hoped that SwiftUI would become more stable over the Summer, but it is still quit buggy and incomplete. While I don't know of any issues with this projects SwiftUI support, I am not using SwiftUI in any of my projects, and consequently cannot vouch for the stability of this project.

ImageSource

You can think of CG/NS/UIImage as a single frame of pixels. ImageSource sits a level below that, providing access to almost anything an image file provides, including metadata and multiple representations. For instance, animated images have multiple image frames as well as timing metadata.

You can access things like count (the number of frames in an animated image) or typeIdentifier to get the kind of file it is. But it's primary use is to generate images:

imageSource.cgImage(at: 3) // frame 3
// with UIKit integration:
imageSource.image(at: 3)

You can provide options on how the image gets generated.

// decode the image data immediately instead of lazily when it gets drawn for the first time
// this is especially useful if you're loading images in a background thread before passing them to the main thread
var options = ImageSource.ImageOptions()
options.shouldDecodeImmediately = false
imageSource.cgImage(options: options)

Creating thumbnails is similar:

imageSource.cgThumbnailImage(size: thumbnailSize, mode: .fill)

Note that image sources don't support cropping, so it will always return an image with the same aspect ratio as the original. If the image contains an embed thumbnail, this can be quit faster than normal thumnail rendering.

Because images sources can reference a file on disk, you can load metadata for an image without loading the entire file into memory. This is especially useful for getting an images size.

ImageSource(url: fileURL).properties(at: 0)?.imageSize

Note that if the image source is being loaded incrementally or references an invalid file, the size will be nil.

Example

To run the example project, clone the repo, and run pod install from the Example directory first.

Installation

In Xcode 11 you can add ImageIOSwift as a package in your project settings using the Github URL of the project. You can then link to the packages you need (ImageIOSwift, ImageIOSwiftUI or ImageIOUIKit).

On macOS, you can use is on the command line by adding the following to your Package.swift:

dependencies: [
	.package(url: "https://github.com/davbeck/ImageIOSwift.git", from: "0.5.0"),
],

Note that because ImageIO is not available on Linux (or any non-Apple platform) that this package cannot be used there.

Add the following line to your Podfile:

pod 'ImageIOSwift'
# one of both of these
pod 'ImageIOSwiftUI'
pod 'ImageIOUIKit'

License

ImageIOSwift is available under the MIT license. See the LICENSE file for more info.

Sample Image Sources

imageioswift's People

Contributors

davbeck avatar patrikthedev avatar wulie88 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

imageioswift's Issues

Unclear error message keep popping up

When I am downloading an image, these error keep popping up in my console log. And btw one question.. is there image caching support?

2019-01-04 17:33:41.219260+0800 ImageIOSwift_Example[33707:774797] [0x7b9c0000a800] Decoding: C0 0x017901F4 0x0000354A 0x11111100 0x00000000 60928
2019-01-04 17:33:41.219493+0800 ImageIOSwift_Example[33707:774797] [0x7b9c0000a800] Options: 377x500 [FFFFFFFF,FFFFFFFF] 00024060
2019-01-04 17:33:42.219564+0800 ImageIOSwift_Example[33707:774797] [0x7b9c00000000] Decoding failed with error code -1

Error in BindableImageSourceController.swift

I get the following error when compiling my app which uses ImageIoSwiftUI:

/Users/ward/Library/Developer/Xcode/DerivedData/Photo_Sorter-exaziycrpvglufdwrvffiyuruhva/SourcePackages/checkouts/ImageIOSwift/Sources/ImageIOSwiftUI/BindableImageSourceController.swift:15:18 Initializer does not override a designated initializer from its superclass

public override init(imageSource: ImageSource) {
	self.objectWillChange = self._willChange.eraseToAnyPublisher()
	self.objectDidChange = self._didChange.eraseToAnyPublisher()
	
	super.init(imageSource: imageSource)
}

This is from the current master version of the package in github

Add support for all ImageIO properties

While technically users can get access to all image properties through the rawValue properties, it would be good to have all CGImageProperties broken out into type safe accessors, as well as any relevant helpers that coalesce different sources (TIFF vs GIF vs PNG etc) into a simple getter.

Additionally, we should consider making the property types specific to the image container or each contained image. Many, if not most properties are only ever available on one or the other, such as size (image only), file size (container only) and orientation (image only). By limiting the types, it can be much more obvious how to get access to certain information.

EXC_BAD_ACCESS in SwiftUI in Xcode Beta 7

Full error: Thread 1: EXC_BAD_ACCESS (code=1, address=0x9)

The error appears on the marked line:

private struct Observer: View {
	@ObservedObject fileprivate var derived: Lazy
	fileprivate var content: (Derived) -> ChildView

	var body: some View {
>>>>		return self.content(derived.value)
	}
}

I'm on the ImageIOSwift 1.0.0 branch using Xcode 11 Beta 7.
In Xcode 11 Beta 6 it worked. Now it doesn't anymore.

Add ImageDestination

The other side of ImageIO, CGImageDestination could also benefit from a Swift wrapper.

It would be interesting to compare performance and memory usage between resizing from a file loaded as an image source directly to an image destination, as apposed to loading a UIImage into memory and drawing it to a new smaller image context (which is by far the most common method).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.