Skip to content

Commit

Permalink
Added a PictureInput using SwiftGD and a sample application to go alo…
Browse files Browse the repository at this point in the history
…ng with it.
  • Loading branch information
BradLarson committed Jun 14, 2019
1 parent c6f86be commit 48b7dc0
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 0 deletions.
4 changes: 4 additions & 0 deletions examples/Linux-OpenGL/SimpleImageFilter/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
16 changes: 16 additions & 0 deletions examples/Linux-OpenGL/SimpleImageFilter/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// swift-tools-version:4.2

import PackageDescription

let package = Package(
name: "SimpleImageFilter",
dependencies: [
.package(path: "../../../../GPUImage2")
],
targets: [
.target(
name: "SimpleImageFilter",
dependencies: ["GPUImage"],
path: "Sources")
]
)
18 changes: 18 additions & 0 deletions examples/Linux-OpenGL/SimpleImageFilter/Sources/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import GPUImage
import Foundation

// For now, GLUT initialization is done in the render window, so that must come first in sequence
let renderWindow = GLUTRenderWindow(width:1280, height:720, title:"Simple Video Filter")
guard let pictureInput = PictureInput(path:"../../SharedAssets/Lambeau.jpg") else {
fatalError("Could not load sample image")
}
let edgeDetection = SobelEdgeDetection()

print("Edge detection")

pictureInput --> edgeDetection --> renderWindow

print("Processing")

pictureInput.processImage(synchronously: true)
renderWindow.loopWithFunction {Thread.sleep(forTimeInterval: 1.0)}
70 changes: 70 additions & 0 deletions framework/Source/Linux/PictureInput.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#if canImport(COpenGL)
import COpenGL
#else
import COpenGLES.gles2
#endif

// apt-get install libgd-dev
import Foundation
import SwiftGD

public class PictureInput: ImageSource {
public let targets = TargetContainer()
var imageFramebuffer:Framebuffer!
var hasProcessedImage:Bool = false

public init?(path:String, smoothlyScaleOutput:Bool = false, orientation:ImageOrientation = .portraitUpsideDown) {
let location = URL(fileURLWithPath: path)
guard let image = Image(url: location) else { return nil }
let bitmapImage = try! image.export(as:.bmp(compression:false))
let widthToUseForTexture = GLint(image.size.width)
let heightToUseForTexture = GLint(image.size.height)

sharedImageProcessingContext.runOperationSynchronously{
do {
self.imageFramebuffer = try Framebuffer(context:sharedImageProcessingContext, orientation:orientation, size:GLSize(width:widthToUseForTexture, height:heightToUseForTexture), textureOnly:true)
print("Framebuffer created")
} catch {
fatalError("ERROR: Unable to initialize framebuffer of size (\(widthToUseForTexture), \(heightToUseForTexture)) with error: \(error)")
}

glBindTexture(GLenum(GL_TEXTURE_2D), self.imageFramebuffer.texture)
// if (smoothlyScaleOutput) {
// glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_LINEAR_MIPMAP_LINEAR)
// }
bitmapImage.withUnsafeBytes { (u8Ptr: UnsafePointer<UInt8>) in
print("Image byte size: \(bitmapImage.count), width: \(widthToUseForTexture), height: \(heightToUseForTexture)")
let imageData = UnsafeRawPointer(u8Ptr) + 54
glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGBA, widthToUseForTexture, heightToUseForTexture, 0, GLenum(GL_RGB), GLenum(GL_UNSIGNED_BYTE), imageData)
}

// if (smoothlyScaleOutput) {
// glGenerateMipmap(GLenum(GL_TEXTURE_2D))
// }
glBindTexture(GLenum(GL_TEXTURE_2D), 0)
}
}

public func processImage(synchronously:Bool = false) {
if synchronously {
sharedImageProcessingContext.runOperationSynchronously{
sharedImageProcessingContext.makeCurrentContext()
self.updateTargetsWithFramebuffer(self.imageFramebuffer)
self.hasProcessedImage = true
}
} else {
sharedImageProcessingContext.runOperationAsynchronously{
sharedImageProcessingContext.makeCurrentContext()
self.updateTargetsWithFramebuffer(self.imageFramebuffer)
self.hasProcessedImage = true
}
}
}

public func transmitPreviousImage(to target:ImageConsumer, atIndex:UInt) {
if hasProcessedImage {
imageFramebuffer.lock()
target.newFramebufferAvailable(imageFramebuffer, fromSourceIndex:atIndex)
}
}
}

0 comments on commit 48b7dc0

Please sign in to comment.