doubleVision 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in doubleVision.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Tristan Hume
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,100 @@
1
+ # DoubleVision
2
+
3
+ I recently was shown trick by a friend where an image was posted on a website
4
+ that displayed one thing in the thumbnail and another in the lightbox.
5
+ http://funnyjunk.com/channel/ponytime/rainbow+dash/llhuDyy/15#15
6
+
7
+ I set out to create a program that generates these images and this is what I came up with.
8
+
9
+ The output images look like this:
10
+
11
+ ![Sample Image](http://f.cl.ly/items/2u1W1J0m2z3N0T0B3K0y/out.png)
12
+
13
+ Try downloading it to your computer and then viewing it. Cool eh?
14
+
15
+ ## How it works
16
+ The PNG specification contains a metadata attribute that allows you to specify the gamma to render the image with. The thing is, not all renderers support this.
17
+
18
+ If an image is created with normal pixels spaced out around a grid of very light-colored pixels.
19
+ The light colored pixels are actually the pixels of the second image reverse-mapped through a gamma function.
20
+ However, they are so light they look white.
21
+
22
+ When the image is displayed with a very low gamma (I use 0.023).
23
+ The normal pixels become almost black and the light pixels become the colors of the second image.
24
+
25
+ Example:
26
+ ![Difference example](https://img.skitch.com/20120427-tjwy5f1gf2xhr9jkfkqi3wxxku.png)
27
+
28
+ ## Why?
29
+ By taking of advantage of this, we can create png files that display a different picture if the renderer supports the gamma attribute.
30
+
31
+ Things that do not support the gamma attribute:
32
+
33
+ - Thumbnail renderers (Facebook, etc...)
34
+ - Apple png rendering
35
+ - Windows png rendering
36
+
37
+ Things that **do** support the gamma attribute:
38
+
39
+ - Firefox (uses libpng wich supports the attribute)
40
+ - Google Chrome
41
+
42
+ This can lead to interesting combos.
43
+ For example:
44
+
45
+ - linking the image on facebook can show one image as a thumbnail but a completely different one when the link is clicked.
46
+ - A picture that detects the user's browser. (Chrome/Firefox or Safari)
47
+ - A picture that displays one thing in the browser and a different thing when downloaded to the user's (victim's) computer.
48
+
49
+ ## Installation
50
+
51
+ Add this line to your application's Gemfile:
52
+
53
+ gem 'doubleVision'
54
+
55
+ And then execute:
56
+
57
+ $ bundle
58
+
59
+ Or install it yourself as:
60
+
61
+ $ gem install doubleVision
62
+
63
+ ## Usage
64
+
65
+ Next, run the program like this:
66
+
67
+ doubleVision withgamma.png withoutgamma.png out.png
68
+
69
+ obviously replacing the filenames with your own.
70
+
71
+ It will combine the images into one image (out.png) that will display
72
+ withgamma.png when viewed with gamma support (e.g. in Firefox)
73
+ and withoutgamma.png when displayed without gamma support (e.g. As a thumbnail)
74
+
75
+ ## Other Example
76
+
77
+ ![Day and Night](http://f.cl.ly/items/1I291E1a1t2O3S2x2i12/DayNight.png)
78
+
79
+ Was generated from:
80
+ ![Night](http://f.cl.ly/items/031k170c3k1i1Q0m0A3X/Night.png)
81
+ and
82
+ ![Day](http://f.cl.ly/items/031k170c3k1i1Q0m0A3X/Day.png)
83
+
84
+ ##FAQ
85
+
86
+ - Why are the images so dark? -
87
+ The images have to be darkened so that they do not show up in the other image.
88
+ One image is also full of black pixels which make it look dark.
89
+ - Are you a wizard?
90
+ Sadly, no. But programmers are almost the same thing.
91
+
92
+ *Disclaimer: Frequently Asked Questions are not necessarily frequently asked, nor are they always questions.*
93
+
94
+ ## Contributing
95
+
96
+ 1. Fork it
97
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
98
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
99
+ 4. Push to the branch (`git push origin my-new-feature`)
100
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "doubleVision"
4
+
5
+ require 'optparse'
6
+
7
+ options = { :gamma => 0.023, :fade1 => 220/255.0, :fade2 => 210/255.0, :shift => 10}
8
+ USAGE = "Usage: doubleVision [options] withgamma.png withoutgamma.png out.png"
9
+
10
+ optParser = OptionParser.new do |opts|
11
+ opts.banner = USAGE
12
+
13
+ opts.separator " "
14
+
15
+ opts.on("-g", "--gamma gamma", Float,
16
+ "Specify the gamma value to use.",
17
+ "Default: #{options[:gamma]}"
18
+ ) { |v| options[:gamma] = v}
19
+
20
+ opts.on("-f","--gammafade fract", Float,
21
+ "Specify the factor used to lower the brightness of the first image.",
22
+ "Needed for images with full white pixels that show up in the non-gamma image.",
23
+ "Default: #{options[:fade1]}"
24
+ ) { |v| options[:fade1] = v}
25
+ opts.on("-F","--nogammafade fract", Float,
26
+ "Specify the factor used to lower the brightness of the second image.",
27
+ "Needed for images with bright pixels that show up in the gamma image.",
28
+ "Default: #{options[:fade2]}"
29
+ ) { |v| options[:fade2] = v}
30
+
31
+ opts.on("-s","--shift fract", Float,
32
+ "Specify the amount to shift up brightness in the first image.",
33
+ "Needed for images with full black pixels that show up in the non-gamma image.",
34
+ "Default: #{options[:shift]}"
35
+ ) { |v| options[:shift] = v}
36
+
37
+ opts.separator ""
38
+
39
+ opts.on("-h", "--help", "Show this help message.") { puts opts; exit }
40
+ end
41
+ optParser.parse!
42
+
43
+ outfile = ARGV[2]
44
+
45
+ puts "Generating image..."
46
+ unless ARGV.length < 3
47
+ DoubleVision.createImageFiles(ARGV[0],ARGV[1],outfile,options)
48
+ else
49
+ puts "Must provide images to use."
50
+ puts optParser
51
+ exit
52
+ end
53
+
54
+ puts "Sucessfully created #{outfile}"
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/doubleVision/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Tristan Hume"]
6
+ gem.email = ["tris.hume@gmail.com"]
7
+ gem.description = %q{Allows you to create magic PNG images that display differently in the browser than in thumbnails.}
8
+ gem.summary = %q{Generates magic thumbnail images.}
9
+ gem.homepage = "https://github.com/trishume/doubleVision"
10
+
11
+ gem.add_runtime_dependency 'chunky_png'
12
+ gem.post_install_message = "Installed! Now run the 'doubleVision' command to try it out."
13
+ gem.bindir = "bin"
14
+ gem.executables << 'doubleVision'
15
+
16
+ gem.files = `git ls-files`.split($\)
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.name = "doubleVision"
19
+ gem.require_paths = ["lib"]
20
+ gem.version = DoubleVision::VERSION
21
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,79 @@
1
+ require "doubleVision/version"
2
+
3
+ require "chunky_png"
4
+
5
+ # Manipulates PNG gamma metadata to create images that
6
+ # display differently when rendered in different clients.
7
+ #
8
+ # Can be used to create images that display differently as
9
+ # thumbnails than when they are clicked on sites like facebook.
10
+ module DoubleVision
11
+ # turns a color component from 0-255 into a new color for the firefox image
12
+ def DoubleVision.trans(num,options)
13
+ scaled = num*options[:fade1] + options[:shift]
14
+ (((scaled/255.0)**(options[:gamma]))*255.0).floor
15
+ end
16
+
17
+ # Takes to ChunkyPNG::Image and returns the chunkypng datastream
18
+ # of an image that displays img1 when rendered with gamma support
19
+ # and img2 without it.
20
+ #
21
+ # Will throw an ArgumentError if the images do not have the same dimensions.
22
+ #
23
+ # Options is a hash containing various parameters
24
+ # [:gamma] is the gamma value to use. This should be a very low value.
25
+ # [:fade1] is the amount to fade the first image. Default is 220/255.0
26
+ # [:fade2] is the amount to fade the second image. Default is 210/255.0
27
+ # [:shift] is the amount to shift up the colours of the second image. Default is 10.
28
+ # The fade and shift parameters are required to properly segment the colors so the algorithm works.
29
+ def DoubleVision.createImage(img1,img2,options = {})
30
+ options[:gamma] ||= 0.023
31
+ options[:fade1] ||= 220/255.0
32
+ options[:fade2] ||= 210/255.0
33
+ options[:shift] ||= 10
34
+
35
+ if img1.dimension != img2.dimension
36
+ raise ArgumentError, "Image sizes must have the same dimensions."
37
+ end
38
+
39
+ out = ChunkyPNG::Image.new(img1.dimension.width*2, img1.dimension.height*2,ChunkyPNG::Color::BLACK)
40
+
41
+ out.dimension.width.times do |x|
42
+ out.dimension.height.times do |y|
43
+ if x % 2 == 0 && y % 2 == 0
44
+ col = img1[x/2,y/2]
45
+ r = trans(ChunkyPNG::Color.r(col),options)
46
+ g = trans(ChunkyPNG::Color.g(col),options)
47
+ b = trans(ChunkyPNG::Color.b(col),options)
48
+ out[x,y] = ChunkyPNG::Color.rgb(r,g,b)
49
+ else
50
+ col = img2[x/2,y/2]
51
+ r = (ChunkyPNG::Color.r(col) * options[:fade2]).round
52
+ g = (ChunkyPNG::Color.g(col) * options[:fade2]).round
53
+ b = (ChunkyPNG::Color.b(col) * options[:fade2]).round
54
+ out[x,y] = ChunkyPNG::Color.rgb(r,g,b)
55
+ end
56
+ end
57
+ end
58
+
59
+ pngGamma = (options[:gamma]*100000).to_i
60
+ # turn the integer into a 4 byte big-endian unsigned int byte string
61
+ bytestr = [pngGamma].pack("L>")
62
+ # The chunk is named gAMA because the PNG spec is weird
63
+ chunk = ChunkyPNG::Chunk::Generic.new("gAMA",bytestr)
64
+ ds = out.to_datastream
65
+ ds.other_chunks << chunk
66
+ ds
67
+ end
68
+
69
+ # Creates a magic image from two png files of the same size.
70
+ # Takes two filenames and saves the result in outFile.
71
+ #
72
+ # Will throw an ArgumentError if the images do not have the same dimensions.
73
+ def DoubleVision.createImageFiles(file1,file2,outFile,options = {})
74
+ img1 = ChunkyPNG::Image.from_file(file1)
75
+ img2 = ChunkyPNG::Image.from_file(file2)
76
+ out = createImage(img1,img2,options)
77
+ out.save(outFile)
78
+ end
79
+ end
@@ -0,0 +1,3 @@
1
+ module DoubleVision
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: doubleVision
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tristan Hume
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: chunky_png
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Allows you to create magic PNG images that display differently in the
31
+ browser than in thumbnails.
32
+ email:
33
+ - tris.hume@gmail.com
34
+ executables:
35
+ - doubleVision
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - .gitignore
40
+ - Gemfile
41
+ - LICENSE
42
+ - README.md
43
+ - Rakefile
44
+ - bin/doubleVision
45
+ - doubleVision.gemspec
46
+ - examples/Day.png
47
+ - examples/DayNight.png
48
+ - examples/Night.png
49
+ - examples/test1.png
50
+ - examples/test2.png
51
+ - examples/testout.png
52
+ - lib/doubleVision.rb
53
+ - lib/doubleVision/version.rb
54
+ homepage: https://github.com/trishume/doubleVision
55
+ licenses: []
56
+ post_install_message: Installed! Now run the 'doubleVision' command to try it out.
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 1.8.23
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Generates magic thumbnail images.
78
+ test_files: []