Created
June 1, 2012 15:26
-
-
Save commuterjoy/2852949 to your computer and use it in GitHub Desktop.
Screenshot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "GD" | |
class Screenshot | |
attr_accessor :frame, :width, :height, :pid, :rate, :quality, :token, :framesPerSourceImage, :programme, :workingCopy | |
# | |
def initialize(opts) | |
# rate at which frames have been extracts - Eg, 1 = 1 fp/s, 0.2 = 1 frame every 5s | |
@rate = 1.0 | |
# frames per source image block | |
@framesPerSourceImage = 28800 / 480 | |
# an instance of GD::Image that gets update with the latest 'copy' of the working image as it's modified/cropped/resized across the class | |
# it's this one you want to serialise to png/jpg | |
@workingCopy | |
# parameters | |
@token = opts['token'] | |
@pid = opts['pid'] | |
# fetch the programme data from redux | |
@programme = Redux::programme @pid, @token | |
@frame = opts['frame'].to_i || (@programme[:duration] / 2) # centre frame if none given | |
@width = ((opts['width']) && opts['width'] > 0) ? opts['width'] : 480 | |
@height = ((opts['height']) && opts['height'] > 0) ? opts['height'] : 270 | |
@quality = opts['quality'] || nil | |
end | |
# Returns a File object containing a screengrab | |
def frame | |
@frameSourceFile = Redux::frames @frame | |
# calculate which file the frame can be found in, Eg, the 321st frame is in the file called '00300.jpg' | |
@sourceFile = "%05d" % ((@frame / 60).floor * 60) | |
@offset = (@frame / @rate) % 60 | |
# open-uri returns a class of type Tempfile, GD requires a class of type File, so we use .path to locate the temporary file via File.new() | |
@workingCopy = GD::Image.newFromJpeg File.new(@frameSourceFile.path) | |
self.crop(480 * @offset, 0, 480, 270) | |
@workingCopy = self.resize(@width, @height) | |
@workingCopy | |
end | |
# Montage, nothing more than a proxy to the image, I.e. no processing required | |
def montage | |
@frameSourceFile = Redux::montage | |
return nil if ( @frameSourceFile == nil) | |
@workingCopy = GD::Image.newFromJpeg File.new(@frameSourceFile.path) | |
@workingCopy | |
end | |
# Returns a cropped image | |
def crop(startX, startY, cropWidth, cropHeight) | |
im = GD::Image.newTrueColor(cropWidth, cropHeight) | |
foo = @workingCopy.copyResampled(im, 0, 0, startX, startY, cropWidth, cropHeight, cropWidth, cropHeight) | |
@workingCopy = im | |
im | |
end | |
# Return a resized image | |
def resize(w, h) | |
im = GD::Image.newTrueColor(w, h) | |
foo = @workingCopy.copyResampled(im, 0, 0, 0, 0, w, h, 480, 270) | |
@workingCopy = im | |
im | |
end | |
# Serialise as a JPEG | |
def to_jpg(quality=@quality) | |
@workingCopy.jpegStr quality | |
end | |
# Serialise as a PNG | |
def to_png | |
@workingCopy.pngStr | |
end | |
# Return the average RGB value of the image working copy | |
def rgb | |
r = 0 | |
g = 0 | |
b = 0 | |
w = @workingCopy.width | |
h = @workingCopy.height | |
pixels = w * h | |
# loop over each pixel from top to bottom, left to right | |
(1..h).each do |y| | |
(1..w).each do |x| | |
pixel = @workingCopy.getPixel(x, y) | |
r += @workingCopy.red(pixel) | |
g += @workingCopy.green(pixel) | |
b += @workingCopy.blue(pixel) | |
end | |
end | |
# .... | |
rgb = [(r/pixels),(g/pixels),(b/pixels)] | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment