doubleVision 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []