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

→‎{{header|Wren}}: Fixed a potential timing issue with FileSystem.load.
m (syntax highlighting fixup automation)
(→‎{{header|Wren}}: Fixed a potential timing issue with FileSystem.load.)
 
(5 intermediate revisions by 3 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]
<syntaxhighlight lang=AutoHotkey"autohotkey">ppm := Run("cmd.exe /c convert lena50.jpg ppm:-")
; pipe in from imagemagick
img := ppm_read("", ppm) ;
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.
 
<syntaxhighlight lang="c">image read_image(const char *name);</syntaxhighlight>
 
<syntaxhighlight lang="c">#include "imglib.h"
 
#define MAXCMDBUF 100
Line 103 ⟶ 258:
return NULL;
}</syntaxhighlight>
 
=={{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.
<syntaxhighlight lang="go">package main
 
// Files required to build supporting package raster are found in:
Line 136 ⟶ 290:
}
}</syntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<syntaxhighlight lang="julia">using Images, FileIO
 
img = load("data/bitmapOutputTest.jpg")
save("data/bitmapOutputTest.ppm", img)</syntaxhighlight>
 
=={{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.
<syntaxhighlight lang="scala">// Version 1.2.40
 
import java.awt.Color
Line 283 ⟶ 435:
}
}</syntaxhighlight>
 
=={{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:
<syntaxhighlight lang="lua">function Bitmap:loadPPM(filename, fp)
if not fp then fp = io.open(filename, "rb") end
if not fp then return end
Line 302 ⟶ 453:
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.
<syntaxhighlight lang=Mathematica"mathematica">Export["data/bitmapOutputTest.ppm",Import["data/bitmapOutputTest.jpg"]];</syntaxhighlight>
 
=={{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"nim">import bitmap
import osproc
import ppm_read
Line 327 ⟶ 476:
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.
<syntaxhighlight lang="ocaml">let read_image ~filename =
if not(Sys.file_exists filename)
then failwith(Printf.sprintf "the file %s does not exist" filename);
Line 338 ⟶ 486:
(img)
;;</syntaxhighlight>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl"># 20211226 Perl programming solution
 
use strict;
Line 370 ⟶ 517:
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"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 409 ⟶ 555:
<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"picolisp">(setq *Ppm (ppmRead '("convert" "img.jpg" "ppm:-")))</syntaxhighlight>
 
=={{header|Python}}==
<syntaxhighlight lang=Python"python">
"""
Adapted from https://stackoverflow.com/questions/26937143/ppm-to-jpeg-jpg-conversion-for-python-3-4-1
Line 430 ⟶ 574:
Does not need to pipe through a conversion utility
because the Pillow module does the conversion.
 
=={{header|Racket}}==
<syntaxhighlight lang="racket">
 
(define (read-ppm port)
Line 464 ⟶ 607:
 
(image->bmp "input.jpg")</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
Line 472 ⟶ 614:
Uses imagemagick convert to pipe the image in.
 
<syntaxhighlight lang="raku" line>class Pixel { has UInt ($.R, $.G, $.B) }
class Bitmap {
has UInt ($.width, $.height);
Line 507 ⟶ 649:
 
See [https://github.com/thundergnat/rc/blob/master/img/camelia.png camelia image here].
 
=={{header|Ruby}}==
Uses [[Raster graphics operations/Ruby]].
 
<syntaxhighlight lang="ruby"># frozen_string_literal: true
 
require_relative 'raster_graphics'
Line 556 ⟶ 697:
bitmap.save('foto.ppm')
</syntaxhighlight>
 
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
{{libheader|Tk}}
<syntaxhighlight lang="tcl">package require Tk
 
proc magickalReadImage {bufferImage fileName} {
Line 570 ⟶ 710:
}
}</syntaxhighlight>
 
=={{header|Wren}}==
{{libheader|DOME}}
Line 578 ⟶ 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.
 
<syntaxhighlight lang=ecmascript"wren">import "graphics" for Canvas, ImageData, Color
import "dome" for Window, Process
import "io" for FileSystem
Line 611 ⟶ 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 666 ⟶ 806:
 
Using the convert utility by ImageMagick:
<syntaxhighlight lang="zkl">p:=System.popen(0'|convert "fractalTree.jpg" ppm:-|,"r");
img:=PPM.readPPM(p); p.close();</syntaxhighlight>
 
{{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