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

→‎{{header|Wren}}: Fixed a potential timing issue with FileSystem.load.
m (→‎{{header|Phix}}: added syntax colouring, marked p2js incompatible)
(→‎{{header|Wren}}: Fixed a potential timing issue with FileSystem.load.)
 
(7 intermediate revisions by 4 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:
<langsyntaxhighlight lang="lua">function Bitmap:loadPPM(filename, fp)
if not fp then fp = io.open(filename, "rb") end
if not fp then return end
Line 300 ⟶ 451:
end
fp:close()
end</langsyntaxhighlight>
Then, for the actual "read-from-pipe" task, a Lua environment that supports <code>io.popen()</code> is required:
<langsyntaxhighlight 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"</langsyntaxhighlight>
 
=={{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.
 
<langsyntaxhighlight Nimlang="nim">import bitmap
import osproc
import ppm_read
Line 326 ⟶ 475:
let image = stream.readPPM()
echo image.w, " ", image.h
p.close()</langsyntaxhighlight>
 
=={{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 337 ⟶ 485:
let img = read_ppm ~ic in
(img)
;;</langsyntaxhighlight>
=={{header|Perl}}==
<syntaxhighlight lang="perl"># 20211226 Perl programming solution
 
use strict;
use warnings;
 
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.
<!--<langsyntaxhighlight Phixlang="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>
Line 376 ⟶ 554:
<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>
<!--</langsyntaxhighlight>-->
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(setq *Ppm (ppmRead '("convert" "img.jpg" "ppm:-")))</langsyntaxhighlight>
 
=={{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 395 ⟶ 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 431 ⟶ 606:
bmp)
 
(image->bmp "input.jpg")</langsyntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
Line 440 ⟶ 614:
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 472 ⟶ 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]].
 
<langsyntaxhighlight lang="ruby"># frozen_string_literal: true
 
require_relative 'raster_graphics'
Line 523 ⟶ 696:
bitmap = Pixmap.open_from_jpeg('foto.jpg')
bitmap.save('foto.ppm')
</syntaxhighlight>
</lang>
 
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
{{libheader|Tk}}
<langsyntaxhighlight lang="tcl">package require Tk
 
proc magickalReadImage {bufferImage fileName} {
Line 537 ⟶ 709:
close $f
}
}</langsyntaxhighlight>
 
=={{header|Wren}}==
{{libheader|DOME}}
Line 546 ⟶ 717:
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.
 
<langsyntaxhighlight ecmascriptlang="wren">import "graphics" for Canvas, ImageData, Color
import "dome" for Window, Process
import "io" for FileSystem
Line 579 ⟶ 750:
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.")
Line 627 ⟶ 799:
}
 
var Game = Bitmap.new("output_piped.jpg", "output_piped.ppm", "output_piped_gs.jpg", 350, 350)</langsyntaxhighlight>
 
=={{header|zkl}}==
Line 634 ⟶ 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