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

From Rosetta Code
Content added Content deleted
(added autohotkey implementation)
(→‎{{header|AutoHotkey}}: changed from ppm3 to ppm6)
Line 7: Line 7:
{{works with | AutoHotkey_L}}
{{works with | AutoHotkey_L}}
Uses [http://www.autohotkey.com/forum/viewtopic.php?t=16823 StdoutTovar.ahk]
Uses [http://www.autohotkey.com/forum/viewtopic.php?t=16823 StdoutTovar.ahk]
<lang AutoHotkey>ppm := Run("cmd.exe /c convert lena50.jpg -compress none ppm:-")
<lang AutoHotkey>ppm := Run("cmd.exe /c convert lena50.jpg ppm:-")
; pipe in from imagemagick
; pipe in from imagemagick
img := ppm_read("", ppm) ;
img := ppm_read("", ppm) ;
x := img[4,4] ; get pixel(4,4)
x := img[4,4] ; get pixel(4,4)
y := img[24,24] ; get pixel(24,24)
msgbox % "img: 4,4,R,G,B, RGB: " x.R ", " x.G ", " x.B ", " x.rgb()
msgbox % x.rgb() " " y.rgb()
img.write("lena50.ppm")
img.write("lena50copy.ppm")
return
return
ppm_read(filename, ppmo=0) ; only ppm3 files supported (ascii)
ppm_read(filename, ppmo=0) ; only ppm6 files supported
{
{
if !ppmo ; if image not already in memory, read from filename
if !ppmo ; if image not already in memory, read from filename
fileread, ppmo, % filename, utf-8
fileread, ppmo, % filename

index := 1
pos := 1

loop, parse, ppmo, `n, `r
loop, parse, ppmo, `n, `r
{
{
if (substr(A_LoopField, 1, 1) == "#")
if (substr(A_LoopField, 1, 1) == "#")
continue
continue
loop,
ppm_nocomment .= A_LoopField "`n"
}
{
if !pos := regexmatch(ppmo, "\d+", pixel, pos)
index := 1
break
pos := 1
while pos := regexmatch(ppm_nocomment, "\d+", pixel, pos)
{
pos := regexmatch(ppm_nocomment, "\s", x, pos)
bitmap%A_Index% := pixel
bitmap%A_Index% := pixel
if (index == 4)
if (index == 4)
Break
Break
pos := regexmatch(ppmo, "\s", x, pos)
index ++
index ++
}
}
}
Line 42: Line 45:
maxcolor := bitmap4
maxcolor := bitmap4
bitmap := Bitmap(width, height, color(0,0,0))
bitmap := Bitmap(width, height, color(0,0,0))
index := 1
index := 1
width := 1
i := 1
height := 1
j := 1
bits := pos
loop % width * height
while pos := regexmatch(ppm_nocomment, "\d+", pixel, pos)
{
{
bitmap[i, j, "r"] := numget(ppmo, 3 * A_Index + bits, "uchar")
pix%index% := pixel
bitmap[i, j, "g"] := numget(ppmo, 3 * A_Index + bits + 1, "uchar")
index++
bitmap[i, j, "b"] := numget(ppmo, 3 * A_Index + bits + 2, "uchar")
if (index > 3)

{
index := 1
if (j == width)
pixel := Color(pix1, pix2, pix3)
bitmap[height, width] := pixel
if (width == bitmap.width)
{
{
width := 1
j := 1
height += 1
i += 1
}
}
else
else
width++
j++
}
}
return bitmap
pos := regexmatch(ppm_nocomment, "\s", x, pos)
}
}

return bitmap
}
#include bitmap_storage.ahk ; from http://rosettacode.org/wiki/Basic_bitmap_storage/AutoHotkey
#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
#include run.ahk ; http://www.autohotkey.com/forum/viewtopic.php?t=16823

Revision as of 04:00, 8 June 2010

Task
Bitmap/Read an image through a pipe
You are encouraged to solve this task according to the task description, using any language you may know.

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 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.

AutoHotkey

Works with: AutoHotkey_L

Uses StdoutTovar.ahk <lang AutoHotkey>ppm := Run("cmd.exe /c convert lena50.jpg ppm:-")

                      ; pipe in from imagemagick

img := ppm_read("", ppm) ; x := img[4,4] ; get pixel(4,4) y := img[24,24] ; get pixel(24,24) msgbox % x.rgb() " " y.rgb() img.write("lena50copy.ppm") return

ppm_read(filename, ppmo=0) ; only ppm6 files supported { if !ppmo  ; if image not already in memory, read from filename

 fileread, ppmo, % filename 
 index := 1  
 pos := 1
 loop, parse, ppmo, `n, `r
 {
   if (substr(A_LoopField, 1, 1) == "#")
     continue

loop, {

if !pos := regexmatch(ppmo, "\d+", pixel, pos)

break

   bitmap%A_Index% := pixel
   if (index == 4)
     Break
   pos := regexmatch(ppmo, "\s", x, pos)
   index ++

}

 }

 type := bitmap1
 width := bitmap2
 height := bitmap3
 maxcolor := bitmap4
 bitmap := Bitmap(width, height, color(0,0,0))
 index := 1
 i := 1
 j := 1
bits := pos 

loop % width * height

 {
     bitmap[i, j, "r"]  := numget(ppmo, 3 * A_Index + bits, "uchar")
     bitmap[i, j, "g"]  := numget(ppmo, 3 * A_Index + bits + 1, "uchar")
     bitmap[i, j, "b"]  := numget(ppmo, 3 * A_Index + bits + 2, "uchar")
     if (j == width)

{ j := 1 i += 1 }

     else

j++ }

return bitmap  
 }
  1. include bitmap_storage.ahk ; from http://rosettacode.org/wiki/Basic_bitmap_storage/AutoHotkey
  2. include run.ahk ; http://www.autohotkey.com/forum/viewtopic.php?t=16823

</lang>

C

Works with: POSIX version .1-2001

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 get_ppm function defined in Read ppm file is used.

<lang c>image read_image(const char *name);</lang>

<lang c>#include "imglib.h"

  1. define MAXCMDBUF 100
  2. define MAXFILENAMELEN 256
  3. define MAXFULLCMDBUF (MAXCMDBUF + MAXFILENAMELEN)

image read_image(const char *name) {

     FILE *pipe;
     char buf[MAXFULLCMDBUF];
     image im;
     
     FILE *test = fopen(name, "r");
     if ( test == NULL ) {
        fprintf(stderr, "cannot open file %s\n", name);
        return NULL;
     }
     fclose(test);
     
     snprintf(buf, MAXFULLCMDBUF, "convert \"%s\" ppm:-", name);
     pipe = popen(buf, "r");
     if ( pipe != NULL )
     {
          im = get_ppm(pipe);
          pclose(pipe);
          return im;
     }
     return NULL;

}</lang>

OCaml

The read_ppm 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. <lang ocaml>let read_image ~filename =

 if not(Sys.file_exists filename)
 then failwith(Printf.sprintf "the file %s does not exist" filename);
 let cmd = Printf.sprintf "convert \"%s\" ppm:-" filename in
 let ic, oc = Unix.open_process cmd in
 let img = read_ppm ~ic in
 (img)
</lang>

Ruby

Extending Read ppm file#Ruby and PPM conversion through a pipe#Ruby. Uses the ImageMagick convert tool.

<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"
   end
   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
   ios.close
   bitmap
 end
 def self.open(filename)
   read_ppm(File.open(filename, 'r'))
 end
 def self.open_from_jpeg(filename)
   read_ppm(IO.popen("convert jpg:#{filename} ppm:-", 'r'))
 end

end

bitmap = Pixmap.open_from_jpeg('file.jpg')</lang>

Tcl

Works with: Tcl version 8.6
Library: Tk

<lang tcl>package require Tk

proc magickalReadImage {bufferImage fileName} {

   set f [open |[list convert [file normalize $fileName] ppm:-] "rb"]
   try {
       $bufferImage put [read $f] -format ppm
   } finally {
       close $f
   }

}</lang>