【问题标题】:best way in linux to display gif gif87a image from C在linux中显示来自C的gif gif87a图像的最佳方法
【发布时间】:2018-06-26 12:13:36
【问题描述】:

在来自 gnu C 而不是 C++ 的 linux 中,最好的方法是在屏幕上显示 gif87a 文件并将其重新显示在屏幕上的相同位置,以便用户可以观察到动态所做的更改数据集?这不是 GIF 动画。

在一些旧代码 (fortran77) 中,它有一个 C 包装器,它获取屏幕上显示的图像并将其写入 gif 文件,有一条关于 X Window Applications Programming, Ed. 2, Johnson & Reichard 的注释用作编写将图像数据显示到屏幕并写入 gif87a 文件的 C 代码,此代码是在 1995 年左右编写的,图像的屏幕显示不再有效(只是一个黑色窗口),但 gif 文件的创建仍然有效。我想做的是来自现有的 C 代码,在 SLES 版本 11.4 中,带有可用于打开 gif 文件并将其显示在屏幕上的库。图像或等高线图有一个颜色条,用户可以设置最小/最大值以根据自己的喜好显示图像,最好让用户轻松高效地调整这些最小最大值重绘图像(重新编写 gif,然后在屏幕上的同一位置重新显示)。还有一些用户可以转动的其他旋钮,例如 dat 的窗口化(汉明或汉),如果用户可以快速/轻松地运行大约 5 种以上的查看图像的方式,然后安顿下来,那将是最好的然后使用在 powerpoint、excel 等中创建的最终 gif 被认为是正确的。

【问题讨论】:

  • 您有正在使用的 GUI 框架吗?那么它可能已经具有加载和显示任意数量的开放和公共图像格式的功能,包括 GIF。
  • 没有 gui 框架,所有当前都以文本形式完成,菜单在 shell/终端中驱动。最终,我想要一个带有滑块和复选框的 gui,它可以通过移动滑块来更改颜色条的最小最大值或对数据应用 han 或 hamming 窗口并重新显示来实时重绘图像

标签: c image x11 gif


【解决方案1】:

编写 X11 应用程序并非易事。您可以使用 ImageMagick 显示 GIF(或大约 200 种图像格式中的任何一种),该图像包含在大多数 Linux 发行版中并且可用于 macOS。 Windows 不算在内。

因此,您可以从命令行创建图像和操作图像,如果需要,也可以在 C 中。所以,让我们创建一个 1024x768 且充满随机颜色的 GIF:

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

现在我们可以显示它了,使用 ImageMagickdisplay 程序:

display image.gif &

现在我们可以通过以下方式获取它的 X11 "window-id"

xprop -root

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

现在您可以随意更改图像,使用滤镜、模糊、形态、阈值和卷积:

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

然后告诉display 程序重绘窗口:

display -window 0x600011 image.gif

这是一个小脚本,它在每帧中间生成带有新数字的图像并更新屏幕:

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


现在您需要做的就是找到一个小的 Python 或 Tcl/Tk 库来绘制一些旋钮和刻度盘,读取它们的位置并相应地更改图像并告诉屏幕重绘。

【讨论】:

  • 使用来自 ImageMagick 的display 说“损坏的图像”但是我可以在 microsoft windows 7 中使用几乎任何应用程序打开我的 gif。我刚刚偶然发现giflibgif2x11 在 linux 的窗口中显示我的 gif
  • 您是否正在运行旧版本的 ImageMagick?试试identify -version 看看。当前版本为 v7.0。能分享一下麻烦的 GIF 吗?
  • Version: ImageMagick 6.4.3 2017-12-11 Q16 OpenMP,在这里共享文件的最佳方式是什么?,gif 文件是 64k,我认为代码将始终写入大小为 580x530 和 256 色的 gif
  • 哎呀!那必须至少有 8 年历史......我认为如果你想继续这条路线,你需要更新。
  • 尝试安装 imagemagick 6.9 或 7.0 导致依赖问题没有提供 libc.so.6 (glibc_2.14)。不知道为什么 6.4 版无法读取 20 多年前格式的 gif,而其他一切都可以。
【解决方案2】:

由于对我的其他答案缺乏热情,我想我会再尝试一次。我快速浏览并了解了 Processing,这是一种非常简单的语言,与 C 非常相似,但更容易编程。

这是它加载 GIF 并显示几个小旋钮的屏幕截图 - 我附加了其中一个以在图像上设置阈值。

这是代码 - 它不是世界上最漂亮的,因为它是我在 Processing 中的第一个代码,但您应该能够看到它在做什么并适应您的需求:

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;
  }

}

这是我使用的一些链接 - image processingP5 library of widgets and knobs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多