This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,5 @@
Many image processing algorithms are defined for [[wp:Grayscale|grayscale]] (or else monochromatic) images. Extend the data storage type defined [[Basic_bitmap_storage|on this page]] to support grayscale images. Define two operations, one to convert a color image to a grayscale image and one for the backward conversion. To get luminance of a color use the formula recommended by [http://www.cie.co.at/index_ie.html CIE]:
L = 0.2126·R + 0.7152·G + 0.0722·B
When using floating-point arithmetic make sure that rounding errors would not cause run-time problems or else distorted results when calculated luminance is stored as an unsigned integer.

View file

@ -0,0 +1,2 @@
---
note: Image processing

View file

@ -0,0 +1 @@
type Grayscale_Image is array (Positive range <>, Positive range <>) of Luminance;

View file

@ -0,0 +1,20 @@
function Grayscale (Picture : Image) return Grayscale_Image is
type Extended_Luminance is range 0..10_000_000;
Result : Grayscale_Image (Picture'Range (1), Picture'Range (2));
Color : Pixel;
begin
for I in Picture'Range (1) loop
for J in Picture'Range (2) loop
Color := Picture (I, J);
Result (I, J) :=
Luminance
( ( 2_126 * Extended_Luminance (Color.R)
+ 7_152 * Extended_Luminance (Color.G)
+ 722 * Extended_Luminance (Color.B)
)
/ 10_000
);
end loop;
end loop;
return Result;
end Grayscale;

View file

@ -0,0 +1,10 @@
function Color (Picture : Grayscale_Image) return Image is
Result : Image (Picture'Range (1), Picture'Range (2));
begin
for I in Picture'Range (1) loop
for J in Picture'Range (2) loop
Result (I, J) := (others => Picture (I, J));
end loop;
end loop;
return Result;
end Color;

View file

@ -0,0 +1,23 @@
w = 143
h = 188
name$ = "Mona_Lisa.jpg"
graphsize w,h
imgload w/2, h/2, name$
fastgraphics
for x = 0 to w-1
for y = 0 to h-1
p = pixel(x,y)
b = p % 256
p = p \256
g = p % 256
p = p \ 256
r = p % 256
l = 0.2126*r + 0.7152*g + 0.0722*b
color rgb(l,l,l)
plot x,y
next y
refresh
next x
imgsave "Grey_"+name$,"jpg"

View file

@ -0,0 +1,29 @@
Width% = 200
Height% = 200
VDU 23,22,Width%;Height%;8,16,16,128
*display c:\lena
FOR y% = 0 TO Height%-1
FOR x% = 0 TO Width%-1
rgb% = FNgetpixel(x%,y%)
r% = rgb% >> 16
g% = (rgb% >> 8) AND &FF
b% = rgb% AND &FF
l% = INT(0.3*r% + 0.59*g% + 0.11*b% + 0.5)
PROCsetpixel(x%,y%,l%,l%,l%)
NEXT
NEXT y%
END
DEF PROCsetpixel(x%,y%,r%,g%,b%)
COLOUR 1,r%,g%,b%
GCOL 1
LINE x%*2,y%*2,x%*2,y%*2
ENDPROC
DEF FNgetpixel(x%,y%)
LOCAL col%
col% = TINT(x%*2,y%*2)
SWAP ?^col%,?(^col%+2)
= col%

View file

@ -0,0 +1,12 @@
typedef unsigned char luminance;
typedef luminance pixel1[1];
typedef struct {
unsigned int width;
unsigned int height;
luminance *buf;
} grayimage_t;
typedef grayimage_t *grayimage;
grayimage alloc_grayimg(unsigned int, unsigned int);
grayimage tograyscale(image);
image tocolor(grayimage);

View file

@ -0,0 +1,9 @@
grayimage alloc_grayimg(unsigned int width, unsigned int height)
{
grayimage img;
img = malloc(sizeof(grayimage_t));
img->buf = malloc(width*height*sizeof(pixel1));
img->width = width;
img->height = height;
return img;
}

View file

@ -0,0 +1,23 @@
grayimage tograyscale(image img)
{
unsigned int x, y;
grayimage timg;
double rc, gc, bc, l;
unsigned int ofs;
timg = alloc_grayimg(img->width, img->height);
for(x=0; x < img->width; x++)
{
for(y=0; y < img->height; y++)
{
ofs = (y * img->width) + x;
rc = (double) img->buf[ofs][0];
gc = (double) img->buf[ofs][1];
bc = (double) img->buf[ofs][2];
l = 0.2126*rc + 0.7152*gc + 0.0722*bc;
timg->buf[ofs][0] = (luminance) (l+0.5);
}
}
return timg;
}

View file

@ -0,0 +1,22 @@
image tocolor(grayimage img)
{
unsigned int x, y;
image timg;
luminance l;
unsigned int ofs;
timg = alloc_img(img->width, img->height);
for(x=0; x < img->width; x++)
{
for(y=0; y < img->height; y++)
{
ofs = (y * img->width) + x;
l = img->buf[ofs][0];
timg->buf[ofs][0] = l;
timg->buf[ofs][1] = l;
timg->buf[ofs][2] = l;
}
}
return timg;
}

View file

@ -0,0 +1 @@
#define free_grayimg(IMG) free_img((image)(IMG))

View file

@ -0,0 +1,23 @@
(in-package #:rgb-pixel-buffer)
(defun rgb-to-gray-image (rgb-image)
(flet ((rgb-to-gray (rgb-value)
(round (+ (* 0.2126 (rgb-pixel-red rgb-value))
(* 0.7152 (rgb-pixel-green rgb-value))
(* 0.0722 (rgb-pixel-blue rgb-value))))))
(let ((gray-image (make-array (array-dimensions rgb-image) :element-type '(unsigned-byte 8))))
(dotimes (i (array-total-size rgb-image))
(setf (row-major-aref gray-image i) (rgb-to-gray (row-major-aref rgb-image i))))
gray-image)))
(export 'rgb-to-gray-image)
(defun grayscale-image-to-pgm-file (image file-name &optional (max-value 255))
(with-open-file (p file-name :direction :output
:if-exists :supersede)
(format p "P2 ~&~A ~A ~&~A" (array-dimension image 1) (array-dimension image 0) max-value)
(dotimes (i (array-total-size image))
(print (row-major-aref image i) p))))
(export 'grayscale-image-to-pgm-file)

View file

@ -0,0 +1,117 @@
module grayscale_image;
import core.stdc.stdio, std.array, std.algorithm, std.string, std.ascii;
public import bitmap;
struct Gray {
ubyte c;
enum black = Gray(0);
enum white = Gray(255);
alias c this;
}
Image!Color loadPGM(Color)(Image!Color img, in string fileName) {
static int readNum(FILE* f) nothrow {
int n;
while (!fscanf(f, "%d ", &n)) {
if ((n = fgetc(f)) == '#') {
while ((n = fgetc(f)) != '\n')
if (n == EOF)
return 0;
} else
return 0;
}
return n;
}
scope(exit) if (fin) fclose(fin);
if (img is null)
img = new Image!Color();
auto fin = fopen(fileName.toStringz(), "rb");
if (!fin)
throw new Exception("Can't open input file.");
if (fgetc(fin) != 'P' ||
fgetc(fin) != '5' ||
!isWhite(fgetc(fin)))
throw new Exception("Not a PGM (PPM P5) image.");
immutable int nc = readNum(fin);
immutable int nr = readNum(fin);
immutable int maxVal = readNum(fin);
if (nc <= 0 || nr <= 0 || maxVal <= 0)
throw new Exception("Wrong input image sizes.");
img.allocate(nc, nr);
auto pix = new ubyte[img.image.length];
immutable count = fread(pix.ptr, 1, nc * nr, fin);
if (count != nc * nr)
throw new Exception("Wrong number of items read.");
pix.copy(img.image);
return img;
}
void savePGM(Color)(in Image!Color img, in string fileName)
in {
assert(img !is null);
assert(!fileName.empty);
assert(img.nx > 0 && img.ny > 0 &&
img.image.length == img.nx * img.ny,
"Wrong image.");
} body {
auto fout = fopen(fileName.toStringz(), "wb");
if (fout == null)
throw new Exception("File can't be opened.");
fprintf(fout, "P5\n%d %d\n255\n", img.nx, img.ny);
auto pix = new ubyte[img.image.length];
foreach (i, ref p; pix)
p = cast(typeof(pix[0]))img.image[i];
immutable count = fwrite(pix.ptr, ubyte.sizeof,
img.nx * img.ny, fout);
if (count != img.nx * img.ny)
new Exception("Wrong number of items written.");
fclose(fout);
}
Gray lumCIE(in RGB c) pure nothrow {
return Gray(cast(ubyte)(0.2126 * c.r +
0.7152 * c.g +
0.0722 * c.b + 0.5));
}
Gray lumAVG(in RGB c) pure nothrow {
return Gray(cast(ubyte)(0.3333 * c.r +
0.3333 * c.g +
0.3333 * c.b + 0.5));
}
Image!Gray rgb2grayImage(alias Conv=lumCIE)(in Image!RGB im) {
auto result = new typeof(return)(im.nx, im.ny);
foreach (i, immutable rgb; im.image)
result.image[i] = Conv(rgb);
return result;
}
Image!RGB gray2rgbImage(in Image!Gray im) {
auto result = new typeof(return)(im.nx, im.ny);
foreach (i, immutable gr; im.image)
result.image[i] = RGB(gr, gr, gr);
return result;
}
version (grayscale_image_main) {
void main() {
auto im1 = new Image!Gray();
im1.loadPGM("lena.pgm");
gray2rgbImage(im1).savePPM6("lena_rgb.ppm");
auto img2 = new Image!RGB();
img2.loadPPM6("quantum_frog.ppm");
img2.rgb2grayImage().savePGM("quantum_frog_grey.pgm");
}
}

View file

@ -0,0 +1,20 @@
function to_gray(sequence image)
sequence color
for i = 1 to length(image) do
for j = 1 to length(image[i]) do
color = and_bits(image[i][j], {#FF0000,#FF00,#FF}) /
{#010000,#0100,#01} -- unpack color triple
image[i][j] = floor(0.2126*color[1] + 0.7152*color[2] + 0.0722*color[3])
end for
end for
return image
end function
function to_color(sequence image)
for i = 1 to length(image) do
for j = 1 to length(image[i]) do
image[i][j] = image[i][j]*#010101
end for
end for
return image
end function

View file

@ -0,0 +1,56 @@
\ grayscale bitmap (without word-alignment for scan lines)
\ bdim, bwidth, bdata all work with graymaps
: graymap ( w h -- gmp )
2dup * bdata allocate throw
dup >r 2! r> ;
: gxy ( x y gmp -- addr )
dup bwidth rot * rot + swap bdata + ;
: g@ ( x y gmp -- c ) gxy c@ ;
: g! ( c x y bmp -- ) gxy c! ;
: gfill ( c gmp -- )
dup bdata swap bdim * rot fill ;
: gshow ( gmp -- )
dup bdim
0 do cr
dup 0 do
over i j rot g@ if [char] * emit else space then
loop
loop
2drop ;
\ RGB <-> Grayscale
: lum>rgb ( 0..255 -- pixel )
dup 8 lshift or
dup 8 lshift or ;
: pixel>rgb ( pixel -- r g b )
256 /mod 256 /mod ;
: rgb>lum ( pixel -- 0..255 )
pixel>rgb
722 * swap
7152 * + swap
2126 * + 10000 / ;
: bitmap>graymap ( bmp -- gmp )
dup bdim graymap
dup bdim nip 0 do
dup bwidth 0 do
over i j rot b@ rgb>lum
over i j rot g!
loop
loop nip ;
: graymap>bitmap ( gmp -- bmp )
dup bdim bitmap
dup bdim nip 0 do
dup bwidth 0 do
over i j rot g@ lum>rgb
over i j rot b!
loop
loop nip ;

View file

@ -0,0 +1,4 @@
type scimage
integer, dimension(:,:), pointer :: channel
integer :: width, height
end type scimage

View file

@ -0,0 +1,7 @@
interface alloc_img
module procedure alloc_img_rgb, alloc_img_sc
end interface
interface free_img
module procedure free_img_rgb, free_img_sc
end interface

View file

@ -0,0 +1,3 @@
interface assignment(=)
module procedure rgbtosc, sctorgb
end interface

View file

@ -0,0 +1,45 @@
subroutine alloc_img_sc(img, w, h)
type(scimage) :: img
integer, intent(in) :: w, h
allocate(img%channel(w, h))
img%width = w
img%height = h
end subroutine alloc_img_sc
subroutine free_img_sc(img)
type(scimage) :: img
if ( associated(img%channel) ) deallocate(img%channel)
end subroutine free_img_sc
subroutine rgbtosc(sc, colored)
type(rgbimage), intent(in) :: colored
type(scimage), intent(inout) :: sc
if ( ( .not. valid_image(sc) ) .and. valid_image(colored) ) then
call alloc_img(sc, colored%width, colored%height)
end if
if ( valid_image(sc) .and. valid_image(colored) ) then
sc%channel = floor(0.2126*colored%red + 0.7152*colored%green + &
0.0722*colored%blue)
end if
end subroutine rgbtosc
subroutine sctorgb(colored, sc)
type(scimage), intent(in) :: sc
type(rgbimage), intent(inout) :: colored
if ( ( .not. valid_image(colored) ) .and. valid_image(sc) ) then
call alloc_img_rgb(colored, sc%width, sc%height)
end if
if ( valid_image(sc) .and. valid_image(colored) ) then
colored%red = sc%channel
colored%green = sc%channel
colored%blue = sc%channel
end if
end subroutine sctorgb

View file

@ -0,0 +1,9 @@
type(scimage) :: gray
type(rgbimage) :: animage
! ... here we "load" or create animage
! while gray must be created or initialized to null
! or errors can arise...
call init_img(gray)
gray = animage
animage = gray
call output_ppm(an_unit, animage)

View file

@ -0,0 +1,100 @@
package raster
import (
"math"
"math/rand"
)
// Grmap parallels Bitmap, but with an element type of uint16
// in place of Pixel.
type Grmap struct {
Comments []string
rows, cols int
px []uint16
pxRow [][]uint16
}
// NewGrmap constructor.
func NewGrmap(x, y int) (b *Grmap) {
g := &Grmap{
Comments: []string{creator}, // creator a const in bitmap source file
rows: y,
cols: x,
px: make([]uint16, x*y),
pxRow: make([][]uint16, y),
}
x0, x1 := 0, x
for i := range g.pxRow {
g.pxRow[i] = g.px[x0:x1]
x0, x1 = x1, x1+x
}
return g
}
func (b *Grmap) Extent() (cols, rows int) {
return b.cols, b.rows
}
func (g *Grmap) Fill(c uint16) {
for i := range g.px {
g.px[i] = c
}
}
func (g *Grmap) SetPx(x, y int, c uint16) bool {
defer func() { recover() }()
g.pxRow[y][x] = c
return true
}
func (g *Grmap) GetPx(x, y int) (uint16, bool) {
defer func() { recover() }()
return g.pxRow[y][x], true
}
// Grmap method of Bitmap, converts (color) Bitmap to (grayscale) Grmap
func (b *Bitmap) Grmap() *Grmap {
g := NewGrmap(b.cols, b.rows)
g.Comments = append([]string{}, b.Comments...)
for i, p := range b.px {
g.px[i] = uint16((int64(p.R)*2126 + int64(p.G)*7152 + int64(p.B)*722) *
math.MaxUint16 / (math.MaxUint8 * 10000))
}
return g
}
// Bitmap method Grmap, converts Grmap to Bitmap. All pixels in the resulting
// color Bitmap will be (very nearly) shades of gray.
func (g *Grmap) Bitmap() *Bitmap {
b := NewBitmap(g.cols, g.rows)
b.Comments = append([]string{}, g.Comments...)
for i, p := range g.px {
roundedSum := int(p) * 3 * math.MaxUint8 / math.MaxUint16
rounded := uint8(roundedSum / 3)
remainder := roundedSum % 3
b.px[i].R = rounded
b.px[i].G = rounded
b.px[i].B = rounded
if remainder > 0 {
odd := rand.Intn(3)
switch odd + (remainder * 3) {
case 3:
b.px[i].R++
case 4:
b.px[i].G++
case 5:
b.px[i].B++
case 6:
b.px[i].G++
b.px[i].B++
case 7:
b.px[i].R++
b.px[i].B++
case 8:
b.px[i].R++
b.px[i].G++
}
}
}
return b
}

View file

@ -0,0 +1,18 @@
module Bitmap.Gray(module Bitmap.Gray) where
import Bitmap
import Control.Monad.ST
newtype Gray = Gray Int deriving (Eq, Ord)
instance Color Gray where
luminance (Gray x) = x
black = Gray 0
white = Gray 255
toNetpbm = map $ toEnum . luminance
fromNetpbm = map $ Gray . fromEnum
netpbmMagicNumber _ = "P5"
netpbmMaxval _ = "255"
toGrayImage :: Color c => Image s c -> ST s (Image s Gray)
toGrayImage = mapImage $ Gray . luminance

View file

@ -0,0 +1,6 @@
NB. converts the image to grayscale according to formula
NB. L = 0.2126*R + 0.7152*G + 0.0722*B
toGray=: [: <. +/ .*"1&0.2126 0.7152 0.0722
NB. converts grayscale image to the color image, with all channels equal
toColor=: 3 & $"0

View file

@ -0,0 +1 @@
viewRGB toColor toGray myimg

View file

@ -0,0 +1,23 @@
void convertToGrayscale(final BufferedImage image){
for(int i=0; i<image.getWidth(); i++){
for(int j=0; j<image.getHeight(); j++){
int color = image.getRGB(i,j);
int alpha = (color >> 24) & 255;
int red = (color >> 16) & 255;
int green = (color >> 8) & 255;
int blue = (color) & 255;
final int lum = (int)(0.2126 * red + 0.7152 * green + 0.0722 * blue);
alpha = (alpha << 24);
red = (lum << 16);
green = (lum << 8);
blue = lum;
color = alpha + red + green + blue;
image.setRGB(i,j,color);
}
}
}

View file

@ -0,0 +1,38 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html><head><script type="text/javascript">
window.addEventListener(
"load", function(){
var img = new Image();
// ***********************************************************
// RUN LOCAL WEBSERVER TO LOAD LOCAL FILES: e.g. python -m http.server (python3)
// ***********************************************************
// img.src = prompt("enter image path","http://localhost:8000/test.jpg");
img.src =
'data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub/\
/ge8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExKcpp\
V0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7';
img.onload = function(){
var can1 = new CustomCanvas("color", img.width, img.height);
var can2 = new CustomCanvas("grayscale", img.width, img.height);
can1.ctx.drawImage(img,0, 0, img.width, img.height);
var imgData = can1.ctx.getImageData(0, 0, can1.w, can1.h);
// desaturate
var avg; var max; var rwgt=0.2126; var gwgt=0.7152; var bwgt=0.0722;
for(var i = 0, max = can1.w*can1.h*4; i < max; i=i+4){
avg = imgData.data[i]*rwgt + imgData.data[i+1]*gwgt + imgData.data[i+2]*bwgt;
imgData.data[i ] = avg; // red
imgData.data[i+1] = avg; // green
imgData.data[i+2] = avg;} // blue, alpha=alpha
can2.ctx.putImageData(imgData, 0, 0);
}
}, false);
function CustomCanvas(id, w, h, s) { /* Custom Canvas Object */
var c = document.createElement("canvas");
c.setAttribute('id', id); c.setAttribute('width', w);
c.setAttribute('height', h); (s)?c.setAttribute('style', s):0;
document.body.appendChild(c, document.body.firstChild);
this.ctx = document.getElementById(id).getContext("2d");
this.w = w; this.h = h;}
</script></head><body></body></html>

View file

@ -0,0 +1,26 @@
function ConvertToGrayscaleImage( bitmap )
local size_x, size_y = #bitmap, #bitmap[1]
local gray_im = {}
for i = 1, size_x do
gray_im[i] = {}
for j = 1, size_y do
gray_im[i][j] = math.floor( 0.2126*bitmap[i][j][1] + 0.7152*bitmap[i][j][2] + 0.0722*bitmap[i][j][3] )
end
end
return gray_im
end
function ConvertToColorImage( gray_im )
local size_x, size_y = #gray_im, #gray_im[1]
local bitmap = Allocate_Bitmap( size_x, size_y ) -- this function is defined at http://rosettacode.org/wiki/Basic_bitmap_storage#Lua
for i = 1, size_x do
for j = 1, size_y do
bitmap[i][j] = { gray_im[i][j], gray_im[i][j], gray_im[i][j] }
end
end
return bitmap
end

View file

@ -0,0 +1,2 @@
function [grayImage] = colortograyscale(inputImage)
grayImage = rgb2gray(inputImage);

View file

@ -0,0 +1,2 @@
toGrayscale[rgb_Image] := ImageApply[#.{0.2126, 0.7152, 0.0722}&, rgb]
toFakeRGB[L_Image] := ImageApply[{#, #, #}&, L]

View file

@ -0,0 +1,21 @@
class BitmapGrayscale extends Bitmap {
public function toGrayscale(){
for ($i = 0; $i < $this->h; $i++){
for ($j = 0; $j < $this->w; $j++){
$l = ($this->data[$j][$i][0] * 0.2126)
+ ($this->data[$j][$i][1] * 0.7152)
+ ($this->data[$j][$i][2] * 0.0722);
$l = round($l);
$this->data[$j][$i] = array($l,$l,$l);
}
}
}
}
$b = new BitmapGrayscale(16,16);
$b->fill(0,0,null,null, array(255,255,0));
$b->setPixel(0, 15, array(255,0,0));
$b->setPixel(0, 14, array(0,255,0));
$b->setPixel(0, 13, array(0,0,255));
$b->toGrayscale();
$b->writeP6('p6-grayscale.ppm');

View file

@ -0,0 +1,27 @@
#! /usr/bin/perl
use strict;
use Image::Imlib2;
sub tograyscale
{
my $img = shift;
my $gimg = Image::Imlib2->new($img->width, $img->height);
for ( my $x = 0; $x < $gimg->width; $x++ ) {
for ( my $y = 0; $y < $gimg->height; $y++ ) {
my ( $r, $g, $b, $a ) = $img->query_pixel($x, $y);
my $gray = int(0.2126 * $r + 0.7152 * $g + 0.0722 * $b);
# discard alpha info...
$gimg->set_color($gray, $gray, $gray, 255);
$gimg->draw_point($x, $y);
}
}
return $gimg;
}
my $animage = Image::Imlib2->load("Lenna100.jpg");
my $gscale = tograyscale($animage);
$gscale->set_quality(80);
$gscale->save("Lennagray.jpg");
exit 0;

View file

@ -0,0 +1,23 @@
# Convert color image (PPM) to greyscale image (PGM)
(de ppm->pgm (Ppm)
(mapcar
'((Y)
(mapcar
'((C)
(/
(+
(* (car C) 2126) # Red
(* (cadr C) 7152) # Green
(* (caddr C) 722) ) # Blue
10000 ) )
Y ) )
Ppm ) )
# Convert greyscale image (PGM) to color image (PPM)
(de pgm->ppm (Pgm)
(mapcar
'((Y)
(mapcar
'((G) (list G G G))
Y ) )
Pgm ) )

View file

@ -0,0 +1,26 @@
# Write greyscale image (PGM) to file
(de pgmWrite (Pgm File)
(out File
(prinl "P5")
(prinl (length (car Pgm)) " " (length Pgm))
(prinl 255)
(for Y Pgm (apply wr Y)) ) )
# Create an empty image of 120 x 90 pixels
(setq *Ppm (make (do 90 (link (need 120)))))
# Fill background with green color
(ppmFill *Ppm 0 255 0)
# Draw a diagonal line
(for I 80 (ppmSetPixel *Ppm I I 0 0 0))
# Convert to greyscale image (PGM)
(setq *Pgm (ppm->pgm *Ppm))
# Write greyscale image to .pgm file
(pgmWrite *Pgm "img.pgm")
# Convert to color image and write to .ppm file
(ppmWrite (pgm->ppm *Pgm) "img.ppm")

View file

@ -0,0 +1,53 @@
# String masquerading as ppm file (version P3)
import io
ppmfileout = io.StringIO('')
def togreyscale(self):
for h in range(self.height):
for w in range(self.width):
r, g, b = self.get(w, h)
l = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
self.set(w, h, Colour(l, l, l))
Bitmap.togreyscale = togreyscale
# Draw something simple
bitmap = Bitmap(4, 4, white)
bitmap.fillrect(1, 0, 1, 2, Colour(127, 0, 63))
bitmap.set(3, 3, Colour(0, 127, 31))
print('Colour:')
# Write to the open 'file' handle
bitmap.writeppmp3(ppmfileout)
print(ppmfileout.getvalue())
print('Grey:')
bitmap.togreyscale()
ppmfileout = io.StringIO('')
bitmap.writeppmp3(ppmfileout)
print(ppmfileout.getvalue())
'''
The print statement above produces the following output :
Colour:
P3
# generated from Bitmap.writeppmp3
4 4
255
255 255 255 255 255 255 255 255 255 0 127 31
255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 127 0 63 255 255 255 255 255 255
255 255 255 127 0 63 255 255 255 255 255 255
Grey:
P3
# generated from Bitmap.writeppmp3
4 4
254
254 254 254 254 254 254 254 254 254 93 93 93
254 254 254 254 254 254 254 254 254 254 254 254
254 254 254 31 31 31 254 254 254 254 254 254
254 254 254 31 31 31 254 254 254 254 254 254
'''

View file

@ -0,0 +1,33 @@
# Conversion from Grey to RGB uses the following code
setAs("pixmapGrey", "pixmapRGB",
function(from, to){
z = new(to, as(from, "pixmap"))
z@red = from@grey
z@green = from@grey
z@blue = from@grey
z@channels = c("red", "green", "blue")
z
})
# Conversion from RGB to grey uses built-in coefficients of 0.3, 0.59, 0.11. To see this, type
getMethods(addChannels)
# We can override this behaviour with
setMethod("addChannels", "pixmapRGB",
function(object, coef=NULL){
if(is.null(coef)) coef = c(0.2126, 0.7152, 0.0722)
z = new("pixmapGrey", object)
z@grey = coef[1] * object@red + coef[2] * object@green +
coef[3] * object@blue
z@channels = "grey"
z
})
# Colour image
plot(p1 <- pixmapRGB(c(c(1,0,0,0,0,1), c(0,1,0,0,1,0), c(0,0,1,1,0,0)), nrow=6, ncol=6))
#Convert to grey
plot(p2 <- as(p1, "pixmapGrey"))
# Convert back to "colour"
plot(p3 <- as(p2, "pixmapRGB"))

View file

@ -0,0 +1,16 @@
/*REXX program to convert a RGB image to grayscale. */
blue='00 00 ff'x /*define the blue color. */
image.=blue /*set the entire IMAGE to blue. */
width= 60 /* width of the IMAGE. */
height=100 /*height " " " */
do j=1 for width
do k=1 for height
r= left(image.j.k,1) ; r=c2d(r) /*extract red & convert*/
g=substr(image.j.k,2,1) ; g=c2d(g) /* " green " " */
b= right(image.j.k,1) ; b=c2d(b) /* " blue " " */
ddd=right(trunc(.2126*r + .7152*g + .0722*b),3,0) /*──► greyscale.*/
image.j.k=right(d2c(ddd,6),3,0) /*... and transform back.*/
end /*j*/
end /*k*/
/*stick a fork in it, we're done.*/

View file

@ -0,0 +1,18 @@
class RGBColour
def to_grayscale
luminosity = Integer(0.2126*@red + 0.7152*@green + 0.0722*@blue)
self.class.new(luminosity, luminosity, luminosity)
end
end
class Pixmap
def to_grayscale
gray = self.class.new(@width, @height)
@width.times do |x|
@height.times do |y|
gray[x,y] = self[x,y].to_grayscale
end
end
gray
end
end

View file

@ -0,0 +1,10 @@
object BitmapOps {
def luminosity(c:Color)=(0.2126*c.getRed + 0.7152*c.getGreen + 0.0722*c.getBlue+0.5).toInt
def grayscale(bm:RgbBitmap)={
val image=new RgbBitmap(bm.width, bm.height)
for(x <- 0 until bm.width; y <- 0 until bm.height; l=luminosity(bm.getPixel(x,y)))
image.setPixel(x, y, new Color(l,l,l))
image
}
}

View file

@ -0,0 +1,13 @@
package require Tk
proc grayscale image {
set w [image width $image]
set h [image height $image]
for {set x 0} {$x<$w} {incr x} {
for {set y 0} {$y<$h} {incr y} {
lassign [$image get $x $y] r g b
set l [expr {int(0.2126*$r + 0.7152*$g + 0.0722*$b)}]
$image put [format "#%02x%02x%02x" $l $l $l] -to $x $y
}
}
}