Skip to content

Instantly share code, notes, and snippets.

@UserAd
Created June 9, 2011 19:00
Show Gist options
  • Save UserAd/1017451 to your computer and use it in GitHub Desktop.
Save UserAd/1017451 to your computer and use it in GitHub Desktop.
Watermark remover
require 'rubygems'
require 'barracuda'
require 'RMagick'
include Magick
include Barracuda
prog = Program.new <<-'eof'
void r2x(int r, int g, int b, double *x, double *y, double *z) {
*x = (( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
*y = (( -38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
*z = (( 112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
}
float diff(int red1, int blue1, int green1, int red2, int blue2, int green2) {
double l1; double a1; double b1;
double x; double y; double z;
r2x(red1, green1, blue1, &l1, &a1, &b1);
r2x(red2, green2, blue2, &x, &y, &z);
double x1 = (l1 - x) * (l1 - x);
double y1 = (a1 - y) * (a1 - y);
double z1 = (b1 - z) * (b1 - z);
return sqrt((float)(x1 + y1 + z1));
}
void mix_colors(int r1, int g1, int b1, int r2, int g2, int b2, int *r, int *g, int *b) {
*r = (int) (r1*0.5 + r2*0.5);
*g = (int) (g1*0.5 + g2*0.5);
*b = (int) (b1*0.5 + b2*0.5);
}
__kernel void clear(__global int *output_red, __global int *output_blue, __global int *output_green, __global int *img1_red, __global int *img1_blue, __global int *img1_green, __global int *img2_red, __global int *img2_blue, __global int *img2_green, __global int *img3_red, __global int *img3_blue, __global int *img3_green) {
double x; double y;double z;
int i = get_global_id(0);
float diff1 = diff(img1_red[i], img1_blue[i], img1_green[i],img2_red[i], img2_blue[i], img2_green[i]);
float diff2 = diff(img1_red[i], img1_blue[i], img1_green[i],img3_red[i], img3_blue[i], img3_green[i]);
float diff3 = diff(img2_red[i], img2_blue[i], img2_green[i],img3_red[i], img3_blue[i], img3_green[i]);
float maximum = max(max(diff1, diff2), diff3);
int r; int g; int b;
if (maximum == diff1) {
mix_colors(img2_red[i], img2_green[i], img2_blue[i], img3_red[i], img3_green[i], img3_blue[i], &r, &g, &b);
} else if (maximum == diff2) {
mix_colors(img1_red[i], img1_green[i], img1_blue[i], img3_red[i], img3_green[i], img3_blue[i], &r, &g, &b);
} else if (maximum == diff3) {
mix_colors(img2_red[i], img2_green[i], img2_blue[i], img1_red[i], img1_green[i], img1_blue[i], &r, &g, &b);
}
output_red[i] = r;
output_blue[i] = b;
output_green[i] = g;
}
eof
images = []
width = 0
height = 0
3.times do |t|
images[t] = Image.read(ARGV[t])[0]
end
width = images.map{|i| i.columns}.max
height = images.map{|i| i.rows}.max
puts "Maximum height: #{height}, width: #{width}"
3.times do |t|
images[t] = images[t].resize(width,height)
end
image_data_red = [[],[],[]] #Buffers to hold image data
image_data_green = [[],[],[]] #Buffers to hold image data
image_data_blue = [[],[],[]] #Buffers to hold image data
width.times do |x|
height.times do |y|
3.times do |t|
pixel = images[t].pixel_color(x,y)
image_data_red[t].push((pixel.red).to_i)
image_data_green[t].push((pixel.green).to_i)
image_data_blue[t].push((pixel.blue).to_i)
end
end
end
result_red = Buffer.new(width * height)
result_blue = Buffer.new(width * height)
result_green = Buffer.new(width * height)
prog.clear(result_red, result_blue, result_green,
(image_data_red[0]), (image_data_blue[0]), (image_data_green[0]),
(image_data_red[1]), (image_data_blue[1]), (image_data_green[1]),
(image_data_red[2]), (image_data_blue[2]), (image_data_green[2])
)
z = 0
res_image = Image.new(width, height)
width.times do |x|
height.times do |y|
res_image.pixel_color x,y, Magick::Pixel.new(result_red[z] , result_green[z] , result_blue[z] )
z = z + 1
end
end
res_image.write('output.png')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment