paint by numbers and then number by painting
March 11, 2009 4:30 PM   Subscribe

How can I convert a list of x, y, R, G, B coordinates into a bitmap?

My previous question asked if there was a way to convert a bitmap into a usable set of x, y, z coordinates. A dead simple solution using the program ImageJ was suggested by kisch mokusch.

But now I need to know how to do this backwards. Meaning, how can I convert a set of [x, y, R, G, B] coordinates back into a bitmap?

Ideally the solution will not involve coding. Is there is an existing solution for this type of thing?
posted by ian1977 to Computers & Internet (10 answers total) 2 users marked this as a favorite
 
are x & y integers? Do you have the full area covered evenly?
posted by aubilenon at 4:43 PM on March 11, 2009


Response by poster:
are x & y integers? Do you have the full area covered evenly?


Yes. The list of x,y RGB values will have been extracted from an existing bitmap, modified via excel or something, and then, hopefully, exported as a bitmap somehow.

So, yeah, the values will all be bitmap friendly.
posted by ian1977 at 4:45 PM on March 11, 2009


In what order are they? If they are in order (all pixels from the first row, from left to right, then all from the second row, etc.), your task will be simpler, as you will be able to ignore the (x, y) numbers.
posted by Monday, stony Monday at 4:50 PM on March 11, 2009


Best answer: Write a PPM file and then use an image-converter program like ImageMagick's convert to convert it to a .bmp.

PPM files are just about the simplest things ever. You have one line that reads:
P3
(just those characters) Then another that reads:
W H
where W is the image's width and H is its height.

Then, for each pixel (starting with the top left, then the top row second from left, etc.) you have 3 numbers from 0-255 (the R, G, B values for the pixel) separated from each other by whitespace.
posted by goingonit at 4:50 PM on March 11, 2009 [1 favorite]


...so if you have an Excel file with your 5-tuples, just sort them first by y, then by x. Then write the remaining 3 columns to a text file, preceded by those "P3" and "W H" lines, and you're done.
posted by goingonit at 4:52 PM on March 11, 2009


Best answer: Untested, but it should work or at least get you close, given a tab-delimited text file, with each 5-tuple (x, y, r, g, b) on its own line:

#!/usr/bin/perl

use warnings;
use strict;
use GD::Simple;

# use standard input to read coordinates into array reference
my $coordinatesRef;
my $index = 0;
while (<>) {
  chomp($_);
  my @coordinates = split("\t", $_);
  $coordinatesRef->[$index]->{x} = $coordinates[0];
  $coordinatesRef->[$index]->{y} = $coordinates[1];
  $coordinatesRef->[$index]->{r} = $coordinates[2];
  $coordinatesRef->[$index]->{g} = $coordinates[3];
  $coordinatesRef->[$index++]->{b} = $coordinates[4];
}

my $img = GD::Simple->new(maxX($coordinatesRef), maxY($coordinatesRef));

foreach my $coordinate (@$coordinatesRef) {
  $img->fgcolor($coordinate->{r}, $coordinate->{g}, $coordinate->{b});
  $img->rectangle($coordinate->{x}, $coordinate->{y}, $coordinate->{x}, $coordinate->{y});
}

print $img->png;

# subroutines

sub maxX {
  my ($coordsRef) = @_;
  my $result = 0;
  foreach my $coord (@$coordsRef) {
    if ($coord->{x} > $result) { $result = $coord->{x}; }
  }
  return $result;
}

sub maxY {
  my ($coordsRef) = @_;
  my $result = 0;
  foreach my $coord (@$coordsRef) {
    if ($coord->{y} > $result) { $result = $coord->{y}; }
  }
  return $result;
}

posted by Blazecock Pileon at 4:58 PM on March 11, 2009


That would be: imgScript.pl < myCoordinates.txt > myBitmap.png
posted by Blazecock Pileon at 5:03 PM on March 11, 2009


Or you could edit it in a text editor and display it in any browser:
<head><title>Your Title Here</title>
<style>
td {width:1px}
tr {height:1px}
</style>
</head>
<body>
<table border='0' cellspacing='0' cellpadding='0'>
<tr>
<td style='background-color: #ffffff'/>
<td style='background-color: #ffffff'/>
<td style='background-color: #ffffff'/>
<td style='background-color: #ffffff'/>
<td style='background-color: #ffffff'/>
<td style='background-color: #ffffff'/>
...
<td style='background-color: #000000'/>
<td style='background-color: #000000'/>
<td style='background-color: #000000'/>
</tr
></table>
</body>
</html>
This uses the pixels in hex; you can also use
<td style='background-color: rgb(255,220,0)'/>
if you prefer decimal red-green-blue

The files are kind of big, but they compress amazingly well.


posted by hexatron at 6:18 PM on March 11, 2009


hexatron needs some sort of prize for cleverest answer. No downloads needed! Here's another web-based version that takes a simple CSV file (no quotes--just numbers, commas and newlines) right on the page by copy-and-paste. It uses the Canvas tag so, with a recent version of Firefox, you can right-click and save the image rather than having to do something silly like doing a print screen and cropping. I took a few minutes to adapt it from a function that does something very similar from a script I made. You'd probably find it even easier than using PPM, because Excel can put out CSV.
posted by abcde at 11:57 PM on March 11, 2009


Oh yeah--be mindful that Firefox might get a bit tremulous if you try to ram a million-line file into a form box. If you want to use my thing and you're dealing with big images, MeMail me and I'll change a couple of lines so you can save the page and have it work off a local file.
posted by abcde at 4:53 AM on March 12, 2009


« Older Looking for a poem.   |   Dark circles, be gone! Newer »
This thread is closed to new comments.