ron
ron

Reputation: 995

best way in linux to display gif gif87a image from C

What would be the best way, in linux from gnu C and not C++, to display a gif87a file on screen and redisplay it in the same location on the screen so the user can observe changes that are made on the fly to the dataset? This is not an animated gif.

in some old code (fortran77) that has a C wrapper which takes an image that was displayed on the screen and writes it to a gif file, there is a comment about X Window Applications Programming, Ed. 2, Johnson & Reichard that was used as a reference to write the C code to display image data to the screen and write a gif87a file, and this code was written around 1995, the onscreen display of the image no longer works (just a black window) but the creation of the gif file still works. What i would like to do is from the existing C code, in SLES version 11.4 with the libraries that are available to open the gif file and display it on screen. The image, or contour plot, has a color bar that the user sets the min/max value for to display the image to their liking and it would be preferable to make it as easy & efficient for the user to adjust those min max values then redraw the image (re-write the gif then redisplay on screen in same location). There's also a handful of other knobs that the user can turn, such as windowing of the dat (hamming or han) and it would be best if the user can quickly/easily run though about 5+ ways of looking at the image before settling on what is considered correct then using that final gif that was created in powerpoint, excel, etc.

Upvotes: 0

Views: 1450

Answers (2)

Mark Setchell
Mark Setchell

Reputation: 207670

As a result of the lack of enthusiasm for my other answer, I thought I'd have another attempt. I had a quick look and learn of Processing which is a very simple language, very similar to C but much easier to program.

Here is a screen shot of it loading a GIF and displaying a couple of twiddly knobs - one of which I attached to do a threshold on the image.

enter image description here

Here's the code - it is not the prettiest in the world because it is my first ever code in Processing but you should be able to see what it is doing and adapt to your needs:

import controlP5.*;

ControlP5 cp5;

int myColorBackground = color(0,0,0);
int knobValue = 100;
float threshold=128;

Knob myKnobA;
Knob myKnobB;

PImage src,dst;  // Declare a variable of type PImage

void setup() {
  size(800,900);

  // Make a new instance of a PImage by loading an image file
  src = loadImage("image.gif");
  // The destination image is created as a blank image the same size as the source.
  dst = createImage(src.width, src.height, RGB);

  smooth();
  noStroke();

  cp5 = new ControlP5(this);

  myKnobA = cp5.addKnob("some knob")
               .setRange(0,255)
               .setValue(50)
               .setPosition(130,650)
               .setRadius(100)
               .setDragDirection(Knob.VERTICAL)
               ;

  myKnobB = cp5.addKnob("threshold")
               .setRange(0,255)
               .setValue(220)
               .setPosition(460,650)
               .setRadius(100)
               .setNumberOfTickMarks(10)
               .setTickMarkLength(4)
               .snapToTickMarks(true)
               .setColorForeground(color(255))
               .setColorBackground(color(0, 160, 100))
               .setColorActive(color(255,255,0))
               .setDragDirection(Knob.HORIZONTAL)
               ;

}

void draw() {
  background(0);
  src.loadPixels();
  dst.loadPixels();

  for (int x = 0; x < src.width; x++) {
    for (int y = 0; y < src.height; y++ ) {
      int loc = x + y*src.width;
      // Test the brightness against the threshold
      if (brightness(src.pixels[loc]) > threshold) {
        dst.pixels[loc]  = color(255);  // White
      }  else {
        dst.pixels[loc]  = color(0);    // Black
      }
    }
  }

  // We changed the pixels in destination
  dst.updatePixels();
  // Display the destination
  image(dst,100,80);
}

void knob(int theValue) {
  threshold = color(theValue);
  println("a knob event. setting background to "+theValue);
}


void keyPressed() {
  switch(key) {
    case('1'):myKnobA.setValue(180);break;
    case('2'):myKnobB.setConstrained(false).hideTickMarks().snapToTickMarks(false);break;
    case('3'):myKnobA.shuffle();myKnobB.shuffle();break;
  }

}

Here are some links I used - image processing, P5 library of widgets and knobs.

Upvotes: 1

Mark Setchell
Mark Setchell

Reputation: 207670

Writing an X11 application is non-trivial. You can display a GIF (or any one of around 200 image formats) using ImageMagick which is included in most Linux distros and is available for macOS. Windows doesn't count.

So, you can create images and manipulate images from the command line, or in C if you want. So, let's create a GIF that is 1024x768 and full of random colours:

convert -size 1024x768 xc:blue +noise random -pointsize 72 -gravity center -annotate 0 "10" image.gif

enter image description here

Now we can display it, using ImageMagick's display program:

display image.gif &

Now we can get its X11 "window-id" with:

xprop -root

...
_NET_ACTIVE_WINDOW(WINDOW): window id # 0x600011
...
...

Now you can change the image, however you like with filters and blurs and morphology and thresholds and convolutions:

convert image.gif -threshold 80% -morphology erode diamond -blur 0x3 -convolve "3x3: -1,0,1, -2,0,2, -1,0,1" ... image.gif

And then tell the display program to redraw the window with:

display -window 0x600011 image.gif

Here is a little script that generates images with a new number in the middle of each frame and updates the screen:

for ((t=0;t<100;t++)) ; do 
   convert -size 640x480 xc:blue +noise random -pointsize 72 -fill white -gravity center -annotate 0 "$t" image.gif
   display -window 0x600011 image.gif
done

enter image description here


Now all you need to do is find a little Python or Tcl/Tk library that draws some knobs and dials, reads their positions and changes the image accordingly and tells the screen to redraw.

Upvotes: 1

Related Questions