Bitmap/Read an image through a pipe: Difference between revisions

→‎{{header|Wren}}: Fixed a potential timing issue with FileSystem.load.
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
(→‎{{header|Wren}}: Fixed a potential timing issue with FileSystem.load.)
 
(17 intermediate revisions by 9 users not shown)
Line 1:
{{task|Raster graphics operations}}
[[Category:Input Output]]
[[Category:Less Than 20 Examples]]
{{task|Raster graphics operations}}
 
This task is the ''opposite'' of the [[PPM conversion through a pipe]]. In this task, using a delegate tool (like '''cjpeg''', one of the netpbm package, or '''convert''' of the ImageMagick package) we read an image file and load it into the data storage type [[Basic bitmap storage|defined here]]. We can also use the code from [[Read ppm file]], so that we can use PPM format like a (natural) bridge between the foreign image format and our simple data storage.
=={{header|ATS}}==
 
I use the <code>magick</code> command from ImageMagick. You need all the source files from [[Bitmap#ATS]], [[Bitmap/Read_a_PPM_file#ATS]], and [[Bitmap/Write_a_PPM_file#ATS]]. (You do ''not'' need the files from [[Grayscale_image#ATS]].)
 
Because I wrote this program by modifying [[Bitmap/PPM_conversion_through_a_pipe#ATS]], it both reads ''and writes'' the file by piping through the <code>magick</code> command of ImageMagick. The comments at the top of the earlier program thus apply doubly here.
 
<syntaxhighlight lang="ats">
(* I both read AND write the image through pipes connected to
ImageMagick. One can also pass options and such but I won't go into
the details. *)
 
(*
 
##myatsccdef=\
patscc -std=gnu2x -g -O2 -DATS_MEMALLOC_LIBC \
-o $fname($1) $1 \
bitmap{,_{read,write}_ppm}_task.{s,d}ats
 
*)
 
#include "share/atspre_staload.hats"
 
staload "bitmap_task.sats"
staload "bitmap_read_ppm_task.sats"
staload "bitmap_write_ppm_task.sats"
 
staload _ = "bitmap_task.dats"
staload _ = "bitmap_read_ppm_task.dats"
staload _ = "bitmap_write_ppm_task.dats"
 
(*------------------------------------------------------------------*)
(* There is support for pipe-I/O in libats/libc, but I cannot (at
least when in a hurry) figure out how it is supposed to be
used. So, as elsewhere in the "raster graphics operations"
category, what is not in the prelude itself I implement with the
foreign function interfaces. :) Using FFI is a typical part of ATS
programming, and one should get used to doing it.
Anyway, here is some UNSAFE support for pipe-I/O. *)
 
typedef charstar = $extype"char *"
typedef FILEstar = $extype"FILE *"
 
fn {}
fileref_popen_unsafe (command : string,
mode : string)
: Option_vt FILEref =
let
val p = $extfcall (ptr, "popen", $UNSAFE.cast{charstar} command,
$UNSAFE.cast{charstar} mode)
in
if iseqz p then
None_vt ()
else
Some_vt ($UNSAFE.cast{FILEref} p)
end
 
fn {}
fileref_pclose_unsafe (f : FILEref)
: int = (* Returns the exit status of the command. *)
$extfcall (int, "pclose", $UNSAFE.cast{FILEstar} f)
 
(*------------------------------------------------------------------*)
 
implement
main0 (argc, argv) =
let
val args = listize_argc_argv (argc, argv)
val nargs = length args
 
val inpf_name = if nargs < 2 then "-" else args[1]
val command = string_append ("magick ", inpf_name, " ppm:-")
val pipe_opt =
(* Temporarily treating a strptr as a string, just to make a
function call of this sort, is not actually unsafe. *)
fileref_popen_unsafe ($UNSAFE.strptr2string command, "r")
val () = free command
in
case+ pipe_opt of
| ~ None_vt () =>
begin
free args;
println! ("For some reason, I failed to open a pipe ",
"for reading from magick.");
exit 1
end
| ~ Some_vt inpf =>
let
val pix_opt = pixmap_read_ppm<rgb24> inpf
in
ignoret (fileref_pclose_unsafe inpf);
case+ pix_opt of
| ~ None_vt () =>
begin
free args;
println! ("For some reason, I failed to pipe the image ",
"from magick.");
exit 1
end
| ~ Some_vt @(pfgc1 | pix1) =>
let
val outf_name = if nargs < 3 then "-" else args[2]
val command = string_append ("magick ppm:- ", outf_name)
val () = free args
val pipe_opt =
(* Temporarily treating a strptr as a string, just to
make a function call of this sort, is not actually
unsafe. *)
fileref_popen_unsafe
($UNSAFE.strptr2string command, "w")
val () = free command
in
case+ pipe_opt of
| ~ None_vt () =>
begin
free (pfgc1 | pix1);
println! ("For some reason, I failed to open a pipe ",
"for writing to magick.");
exit 3
end
| ~ Some_vt outf =>
let
val success = pixmap_write_ppm<rgb24> (outf, pix1)
in
ignoret (fileref_pclose_unsafe outf);
free (pfgc1 | pix1);
if ~success then
begin
println! ("For some reason, I failed to pipe ",
"the image to magick.");
exit 2
end
end
end
end
end
</syntaxhighlight>
 
{{out}}
 
Using SIPI test image 4.1.07:
 
<pre>$ myatscc bitmap_read_through_pipe_task.dats
$ ./bitmap_read_through_pipe_task 4.1.07.tiff > 4.1.07.ppm
$ file 4.1.07.ppm
4.1.07.ppm: Netpbm image data, size = 256 x 256, rawbits, pixmap
$ ./bitmap_read_through_pipe_task 4.1.07.tiff 4.1.07.jpg
$ file 4.1.07.jpg
4.1.07.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 256x256, components 3</pre>
 
Notice that, when I did not specify an output file, I got a PPM (PPM being what was sent through the output pipe to magick). Both times, though, the input pipe converts a TIFF image to PPM, which then is read into the internal <code>pixmap</code> type.
 
Here is the JPEG that was outputted:
[[File:Bitmap read through pipe task ATS.jpg|none|alt=SIPI test image of jellybeans.]]
 
=={{header|AutoHotkey}}==
{{works with | AutoHotkey_L}}
Uses [http://www.autohotkey.com/forum/viewtopic.php?t=16823 StdoutTovar.ahk]
<langsyntaxhighlight AutoHotkeylang="autohotkey">ppm := Run("cmd.exe /c convert lena50.jpg ppm:-")
; pipe in from imagemagick
img := ppm_read("", ppm) ;
Line 67 ⟶ 222:
#include bitmap_storage.ahk ; from http://rosettacode.org/wiki/Basic_bitmap_storage/AutoHotkey
#include run.ahk ; http://www.autohotkey.com/forum/viewtopic.php?t=16823
</syntaxhighlight>
</lang>
 
=={{header|C}}==
Line 73 ⟶ 228:
Here I've used '''convert''' by ImageMagick. It is up to the program to ''understand'' the source file type; in this way, we can read theoretically any image format ImageMagick can handle. The <tt>get_ppm</tt> function defined in [[Read ppm file]] is used.
 
<langsyntaxhighlight lang="c">image read_image(const char *name);</langsyntaxhighlight>
 
<langsyntaxhighlight lang="c">#include "imglib.h"
 
#define MAXCMDBUF 100
Line 102 ⟶ 257:
}
return NULL;
}</langsyntaxhighlight>
 
=={{header|Go}}==
This example uses convert to convert the test image for the flood fill task. It reads through the pipe as required for this task, then writes as a .ppm file convenient for the flood fill task.
<langsyntaxhighlight lang="go">package main
 
// Files required to build supporting package raster are found in:
Line 135 ⟶ 289:
log.Fatal(err)
}
}</langsyntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<langsyntaxhighlight lang="julia">using Images, FileIO
 
img = load("data/bitmapOutputTest.jpg")
save("data/bitmapOutputTest.ppm", img)</langsyntaxhighlight>
 
=={{header|Kotlin}}==
{{works with|Ubuntu 16.04}}
The code for this is similar to that for the [[Bitmap/Read a PPM file]] task except that the .jpg file is converted via a pipe to .ppm format using the ImageMagick 'convert' tool and stored in a BasicBitmapStorage object. It is then converted to grayscale and saved back to disk as a .jpg file.
<langsyntaxhighlight lang="scala">// Version 1.2.40
 
import java.awt.Color
Line 282 ⟶ 434:
}
}
}</langsyntaxhighlight>
=={{header|Lua}}==
Uses Bitmap class [[Bitmap#Lua|here]], with an RGB tuple pixel representation, and the rudimentary PPM support [[Bitmap/Flood_fill#Lua|here]], and the Lenna image [[:File:Lenna100.jpg|here]].
 
First, the <code>loadPPM()</code> method is altered to allow passing an existing file handle:
=={{header|Mathematica}}==
<syntaxhighlight lang="lua">function Bitmap:loadPPM(filename, fp)
if not fp then fp = io.open(filename, "rb") end
if not fp then return end
local head, width, height, depth, tail = fp:read("*line", "*number", "*number", "*number", "*line")
self.width, self.height = width, height
self:alloc()
for y = 1, self.height do
for x = 1, self.width do
self.pixels[y][x] = { string.byte(fp:read(1)), string.byte(fp:read(1)), string.byte(fp:read(1)) }
end
end
fp:close()
end</syntaxhighlight>
Then, for the actual "read-from-pipe" task, a Lua environment that supports <code>io.popen()</code> is required:
<syntaxhighlight lang="lua">local bitmap = Bitmap(0,0)
fp = io.popen("magick Lenna100.jpg ppm:-", "rb")
bitmap:loadPPM(nil, fp)
 
bitmap:savePPM("Lenna100.ppm") -- just as "proof"</syntaxhighlight>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Based off the Julia program.
<langsyntaxhighlight Mathematicalang="mathematica">Export["data/bitmapOutputTest.ppm",Import["data/bitmapOutputTest.jpg"]];</langsyntaxhighlight>
=={{header|Nim}}==
Using "jpegtopnm" from Netpbm suite. Input is a JPEG file and result (the PPM file) is sent to stdout. The procedure "readPPM" reads directly from the stream and build the image container.
 
<syntaxhighlight lang="nim">import bitmap
import osproc
import ppm_read
import streams
 
# Launch Netpbm "jpegtopnm".
# Input is taken from "input.jpeg" and result sent to stdout.
let p = startProcess("jpegtopnm", args = ["input.jpeg"], options = {poUsePath})
let stream = FileStream(p.outputStream())
let image = stream.readPPM()
echo image.w, " ", image.h
p.close()</syntaxhighlight>
=={{header|OCaml}}==
The <code>read_ppm</code> function of the page [[read ppm file]] and used by the code below would need to be changed to take as parameter an input channel instead of the filename.
<langsyntaxhighlight lang="ocaml">let read_image ~filename =
if not(Sys.file_exists filename)
then failwith(Printf.sprintf "the file %s does not exist" filename);
Line 297 ⟶ 485:
let img = read_ppm ~ic in
(img)
;;</langsyntaxhighlight>
=={{header|Perl}}==
<syntaxhighlight lang="perl"># 20211226 Perl programming solution
 
use strict;
=={{header|PicoLisp}}==
use warnings;
<lang PicoLisp>(setq *Ppm (ppmRead '("convert" "img.jpg" "ppm:-")))</lang>
 
use Imager;
 
my $raw;
 
open my $fh, '-|', 'cat Lenna50.jpg' or die;
binmode $fh;
while ( sysread $fh , my $chunk , 1024 ) { $raw .= $chunk }
close $fh;
 
my $enable = $Imager::formats{"jpeg"}; # some kind of tie ?
 
my $IO = Imager::io_new_buffer $raw or die;
my $im = Imager::File::JPEG::i_readjpeg_wiol $IO or die;
 
open my $fh2, '>', 'output.ppm' or die;
binmode $fh2;
my $IO2 = Imager::io_new_fd(fileno $fh2);
Imager::i_writeppm_wiol $im, $IO2 ;
close $fh2;
undef($im);</syntaxhighlight>
{{out}}
<pre>file output.ppm
output.ppm: Netpbm PPM "rawbits" image data, size = 512 x 512
magick identify output.ppm
output.ppm PPM 512x512 512x512+0+0 8-bit sRGB 786464B 0.000u 0:00.014</pre>
=={{header|Phix}}==
Uses the demo\rosetta\viewppm.exw utility to accomplish this task.<br>
The returned data is raw binary, so you can either write it direct or chuck it through read_ppm/write_ppm.
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Bitmap_Read_an_image_through_a_pipe.exw</span>
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- file i/o, system_exec(), pipes[!!]</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">pipeio</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">ppm</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> <span style="color: #000080;font-style:italic;">-- read_ppm(), write_ppm()</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">pipes</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">pipes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">PIPOUT</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">create_pipe</span><span style="color: #0000FF;">(</span><span style="color: #000000;">INHERIT_READ</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- Create the child process, with replacement stdout. </span>
<span style="color: #004080;">string</span> <span style="color: #000000;">cmd</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%s viewppm -load test.jpg"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">get_interpreter</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)})</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">hProc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">system_exec</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cmd</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pipes</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">hPipe</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pipes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">PIPOUT</span><span style="color: #0000FF;">][</span><span style="color: #000000;">READ_PIPE</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">ppm</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">read_from_pipe</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hPipe</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hProc</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">chunk</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">read_from_pipe</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hPipe</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hProc</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">chunk</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">ppm</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">chunk</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #000000;">pipes</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">close_handles</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pipes</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">img</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">read_ppm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ppm</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bText</span><span style="color: #0000FF;">:=</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">write_ppm</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Lenapipe.ppm"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">img</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">else</span> <span style="color: #000080;font-style:italic;">-- or</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Lenapipe.ppm"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"wb"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ppm</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #0000FF;">?</span><span style="color: #008000;">"done"</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
=={{header|PicoLisp}}==
<syntaxhighlight lang="picolisp">(setq *Ppm (ppmRead '("convert" "img.jpg" "ppm:-")))</syntaxhighlight>
=={{header|Python}}==
<syntaxhighlight lang="python">
<lang Python>
"""
Adapted from https://stackoverflow.com/questions/26937143/ppm-to-jpeg-jpg-conversion-for-python-3-4-1
Line 316 ⟶ 571:
im = Image.open("boxes_1.jpg")
im.save("boxes_1v2.ppm")
</syntaxhighlight>
</lang>
Does not need to pipe through a conversion utility
because the Pillow module does the conversion.
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
 
(define (read-ppm port)
Line 352 ⟶ 606:
bmp)
 
(image->bmp "input.jpg")</langsyntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2017.09}}
Uses pieces from [[Bitmap#Perl_6Raku| Bitmap]] and [[Bitmap/Read_a_PPM_file#Perl_6Raku| Read a PPM file]] tasks. Included here to make a complete, runnable program.
 
Uses imagemagick convert to pipe the image in.
 
<syntaxhighlight lang="raku" perl6line>class Pixel { has UInt ($.R, $.G, $.B) }
class Bitmap {
has UInt ($.width, $.height);
Line 393 ⟶ 646:
{ Pixel.new(R => .[0], G => .[1], B => .[2]) };
 
'./camelia.ppm'.IO.open(:bin, :w).write: $b.P6;</langsyntaxhighlight>
 
See [https://github.com/thundergnat/rc/blob/master/img/camelia.png camelia image here].
 
=={{header|Ruby}}==
Uses [[Raster graphics operations/Ruby]].
Extending [[Read ppm file#Ruby]] and [[PPM conversion through a pipe#Ruby]]. Uses the ImageMagick <code>convert</code> tool.
 
<syntaxhighlight lang="ruby"># frozen_string_literal: true
 
require_relative 'raster_graphics'
 
<lang ruby>class Pixmap
def self.read_ppm(ios)
format = ios.gets.chomp
width, height = ios.gets.chomp.split.map {|n| n.(&:to_i })
max_colour = ios.gets.chomp
 
if (not !PIXMAP_FORMATS.include?(format)) or ||
(width < 1) or|| (height < 1) or||
(max_colour != '255')
then
ios.close
raise StandardError, "file '#{filename}' does not start with the expected header"
Line 415 ⟶ 670:
ios.binmode if PIXMAP_BINARY_FORMATS.include?(format)
 
bitmap = self.new(width, height)
height.times do |y|
width.times do |x|
# read 3 bytes
red, green, blue = case format
when 'P3' then ios.gets.chomp.split
when 'P6' then ios.read(3).unpack('C3')
end
bitmap[x, y] = RGBColour.new(red, green, blue)
end
end
Line 439 ⟶ 694:
end
 
bitmap = Pixmap.open_from_jpeg('filefoto.jpg')</lang>
bitmap.save('foto.ppm')
 
</syntaxhighlight>
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
{{libheader|Tk}}
<langsyntaxhighlight lang="tcl">package require Tk
 
proc magickalReadImage {bufferImage fileName} {
Line 453 ⟶ 709:
close $f
}
}</langsyntaxhighlight>
=={{header|Wren}}==
{{libheader|DOME}}
As DOME doesn't have a method for calling an external process (''ImageMagick'' in this case), we re-use the small plug-in (''pipeconv.so'') we created in the 'PPM conversion through a pipe' task
to add this functionality.
 
We can now use this plug-in in the following script which calls ''ImageMagick'' to convert the ''output_piped.jpg'' file to a ''ppm'' file so that we can load the latter, convert it to a gray scale image, display it and save it to a .jpg file.
 
<syntaxhighlight lang="wren">import "graphics" for Canvas, ImageData, Color
import "dome" for Window, Process
import "io" for FileSystem
import "plugin" for Plugin
 
Plugin.load("pipeconv")
 
import "pipeconv" for PipeConv
 
class Bitmap {
construct new(fileName, fileName2, fileName3, width, height) {
Window.title = "Bitmap - read image via pipe"
Window.resize(width, height)
Canvas.resize(width, height)
_w = width
_h = height
_fn3 = fileName3
// convert .jpg file to .ppm via a pipe
PipeConv.convert(fileName, fileName2)
// load the .ppm file
loadPPMFile(fileName2)
}
 
init() {
toGrayScale()
// display gray scale image
_bmp2.draw(0, 0)
// save it to file
_bmp2.saveToFile(_fn3)
}
 
loadPPMFile(fileName) {
var ppm = FileSystem.load(fileName)
var count = ppm.count //ensure file is fully loaded before proceeding
if (ppm[0..1] != "P6") {
System.print("The loaded file is not a P6 file.")
Process.exit()
}
var lines = ppm.split("\n")
if (Num.fromString(lines[2]) > 255) {
System.print("The maximum color value can't exceed 255.")
Process.exit()
}
var wh = lines[1].split(" ")
var w = Num.fromString(wh[0])
var h = Num.fromString(wh[1])
_bmp = ImageData.create(fileName, w, h)
var bytes = ppm.bytes
var i = bytes.count - 3 * w * h
for (y in 0...h) {
for (x in 0...w) {
var r = bytes[i]
var g = bytes[i+1]
var b = bytes[i+2]
var c = Color.rgb(r, g, b)
pset(x, y, c)
i = i + 3
}
}
}
 
toGrayScale() {
_bmp2 = ImageData.create("gray scale", _bmp.width, _bmp.height)
for (x in 0..._bmp.width) {
for (y in 0..._bmp.height) {
var c1 = _bmp.pget(x, y)
var lumin = (0.2126 * c1.r + 0.7152 * c1.g + 0.0722 * c1.b).floor
var c2 = Color.rgb(lumin, lumin,lumin, c1.a)
_bmp2.pset(x, y, c2)
}
}
}
 
pset(x, y, col) { _bmp.pset(x, y, col) }
 
pget(x, y) { _bmp.pget(x, y) }
 
update() {}
 
draw(alpha) {}
}
 
var Game = Bitmap.new("output_piped.jpg", "output_piped.ppm", "output_piped_gs.jpg", 350, 350)</syntaxhighlight>
 
=={{header|zkl}}==
Line 460 ⟶ 806:
 
Using the convert utility by ImageMagick:
<langsyntaxhighlight lang="zkl">p:=System.popen(0'|convert "fractalTree.jpg" ppm:-|,"r");
img:=PPM.readPPM(p); p.close();</langsyntaxhighlight>
 
{{omit from|PARI/GP}}
{{omit from|TI-83 BASIC}} {{omit from|TI-89 BASIC}} <!-- Does not have an external OS/command processor. -->
{{omit from|TI-89 BASIC}} <!-- Does not have an external OS/command processor. -->
[[Category:Less Than 20 Examples]]
9,476

edits