Skip to content

Instantly share code, notes, and snippets.

@commuterjoy
Created June 1, 2012 15:26
Show Gist options
  • Save commuterjoy/2852949 to your computer and use it in GitHub Desktop.
Save commuterjoy/2852949 to your computer and use it in GitHub Desktop.
Screenshot
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