FLTK - FLTK1.4.1 - demo - animgifimage

文章目录

    • FLTK - FLTK1.4.1 - demo - animgifimage
    • 概述
    • 笔记
    • END

FLTK - FLTK1.4.1 - demo - animgifimage

概述

知识点:
注册图像文件类型判断回调
FLTK支持的图像格式 GIF, BMP, ICO, PNM, PNG, jpg, svg
事件回调的注册
GIF图像显示为图片或动画的标志设置
// 超时回调的设置和移除, 超时回调是一次性的,如果还需要同一个超时回调,需要再次设置超时回调
// 文件选择器UI的调用和返回
// 用户选择通过文件选择器选择的文件,有可能不是指定尾缀的文件类型
// fltk窗口的遍历
// fltk窗口 背景颜色设置 Fl_Color
// fltk窗口退出回调的设置
// 图像数据载入成功和图像数据有效的判断
// 图像关键数据(长,宽,帧数)的取得
// fltk窗口类的copy_x()是复制了一份数据,并不是指向原始数据
// fltk图像类禁用缓存
// fltk窗体禁止响应快捷键的窗体size缩放
// 等待当前窗体正常结束
// fltk类的构造函数是通过弹窗来报错的(e.g. 图像文件格式错), 这个报错信息不是API调用者能控制的。

笔记

// FLTK - FLTK1.4.1 - demo - animgifimage
/*
知识点:注册图像文件类型判断回调FLTK支持的图像格式 GIF, BMP, ICO, PNM, PNG, jpg, svg事件回调的注册GIF图像显示为图片或动画的标志设置// 超时回调的设置和移除, 超时回调是一次性的,如果还需要同一个超时回调,需要再次设置超时回调// 文件选择器UI的调用和返回// 用户选择通过文件选择器选择的文件,有可能不是指定尾缀的文件类型// fltk窗口的遍历// fltk窗口 背景颜色设置 Fl_Color// fltk窗口退出回调的设置// 图像数据载入成功和图像数据有效的判断// 图像关键数据(长,宽,帧数)的取得// fltk窗口类的copy_x()是复制了一份数据,并不是指向原始数据// fltk图像类禁用缓存// fltk窗体禁止响应快捷键的窗体size缩放// 等待当前窗体正常结束// fltk类的构造函数是通过弹窗来报错的(e.g. 图像文件格式错), 这个报错信息不是API调用者能控制的。
*/#include "fltk_test.h"// 如果要将fl demo的实现搬过来测试,就注释掉下面的宏
// #define DONT_USE_FL_DEMO#ifdef DONT_USE_FL_DEMO
int fl_demo_main(int argc, char** argv)
{return 0;
}#else#endif // TEST_FL_DEMO//
//  Test program for displaying animated GIF files using the
//  Fl_Anim_GIF_Image class.
//
#include <FL/Fl_Anim_GIF_Image.H>#include <FL/Fl_Double_Window.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/Fl_Shared_Image.H>
#include <FL/Fl_Tiled_Image.H>
#include <stdlib.h>static int g_good_count = 0, g_bad_count = 0, g_frame_count = 0;static const Fl_Color BackGroundColor = FL_GRAY; // use e.g. FL_RED to see// transparent parts better
static const double RedrawDelay = 30 /* 1. / 20*/ ;         // interval [sec] for forced redrawstatic void quit_cb(Fl_Widget* w_, void*) {exit(0);
}static void set_title(Fl_Window* win, Fl_Anim_GIF_Image* animgif) {char buf[200];snprintf(buf, sizeof(buf), "%s (%d frames)  %2.2fx", fl_filename_name(animgif->name()),animgif->frames(), animgif->speed());if (animgif->frame_uncache())strcat(buf, " U");// fltk窗口类的copy_x()是复制了一份数据,并不是指向原始数据win->copy_label(buf);win->copy_tooltip(buf);
}static void cb_forced_redraw(void* d) {// fltk窗口的遍历Fl_Window* win = Fl::first_window();while (win) {if (!win->menu_window())win->redraw();win = Fl::next_window(win);}if (Fl::first_window())Fl::repeat_timeout(RedrawDelay, cb_forced_redraw);
}Fl_Window* openFile(const char* name, char* flags, bool close = false) {// determine test options from 'flags'bool uncache = strchr(flags, 'u');char* d = flags - 1;int debug = 0;while ((d = strchr(++d, 'd'))) debug++;bool optimize_mem = strchr(flags, 'm');bool desaturate = strchr(flags, 'D');bool average = strchr(flags, 'A');bool test_tiles = strchr(flags, 'T');bool test_forced_redraw = strchr(flags, 'f');char* r = strchr(flags, 'r');bool resizable = r && !test_tiles;double scale = 1.0;if (r && resizable) scale = atof(r + 1);if (scale <= 0.1 || scale > 5)scale = resizable ? 0.7 : 1.0;// setup windowFl::remove_timeout(cb_forced_redraw);Fl_Double_Window* win = new Fl_Double_Window(300, 300);// fltk窗口 背景颜色设置 Fl_Colorwin->color(BackGroundColor);if (close){// fltk窗口退出回调的设置win->callback(quit_cb);}printf("Loading '%s'%s%s ... ", name,uncache ? " (uncached)" : "",optimize_mem ? " (optimized)" : "");// create a canvas for the animationFl_Box* canvas = test_tiles ? 0 : new Fl_Box(0, 0, 0, 0); // canvas will be resized by animationFl_Box* canvas2 = 0;unsigned short gif_flags = debug ? Fl_Anim_GIF_Image::LOG_FLAG : 0;if (debug > 1)gif_flags |= Fl_Anim_GIF_Image::DEBUG_FLAG;if (optimize_mem)gif_flags |= Fl_Anim_GIF_Image::OPTIMIZE_MEMORY;// create animation, specifying this canvas as display widget// fltk类的构造函数是通过弹窗来报错的(e.g. 图像文件格式错), 这个报错信息不是API调用者能控制的。Fl_Anim_GIF_Image* animgif = new Fl_Anim_GIF_Image(name, canvas, gif_flags);// 图像数据载入成功和图像数据有效的判断bool good(animgif->ld() == 0 && animgif->valid());// 图像关键数据(长,宽,帧数)的取得printf("%s: %d x %d (%d frames) %s\n",animgif->name(), animgif->w(), animgif->h(), animgif->frames(), good ? "OK" : "ERROR");// for the statistics (when run on testsuite):g_good_count += good;g_bad_count += !good;g_frame_count += animgif->frames();// 设置窗体的用户数据win->user_data(animgif); // store address of image (see note in main())// exercise the optional tests on the animation// fltk图像类禁用缓存animgif->frame_uncache(uncache);if (scale != 1.0) {animgif->resize(scale);printf("TEST: resized %s by %.2f to %d x %d\n", animgif->name(), scale, animgif->w(), animgif->h());}if (average) {printf("TEST: color_average %s\n", animgif->name());animgif->color_average(FL_GREEN, 0.5); // currently hardcoded}if (desaturate) {printf("TEST: desaturate %s\n", animgif->name());animgif->desaturate();}int W = animgif->w();int H = animgif->h();if (animgif->frames()) {if (test_tiles) {// demonstrate a way how to use the animation with Fl_Tiled_Imageprintf("TEST: use %s as tiles\n", animgif->name());W *= 2;H *= 2;Fl_Tiled_Image* tiled_image = new Fl_Tiled_Image(animgif);Fl_Group* group = new Fl_Group(0, 0, win->w(), win->h());group->image(tiled_image);group->align(FL_ALIGN_INSIDE);animgif->canvas(group, Fl_Anim_GIF_Image::DONT_RESIZE_CANVAS | Fl_Anim_GIF_Image::DONT_SET_AS_IMAGE);win->resizable(group);}else {// demonstrate a way how to use same animation in another canvas simultaneously:// as the current implementation allows only automatic redraw of one canvas..if (test_forced_redraw) {if (W < 400) {printf("TEST: open %s in another animation with application redraw\n", animgif->name());canvas2 = new Fl_Box(W, 0, animgif->w(), animgif->h()); // another canvas for animationcanvas2->image(animgif); // is set to same animation!W *= 2;Fl::add_timeout(RedrawDelay, cb_forced_redraw); // force periodic redraw}}}// make window resizable (must be done before show())if (resizable && canvas && !test_tiles) {win->resizable(win);}win->size(W, H); // change to actual size of canvas// start the animationwin->end();win->show();win->wait_for_expose();set_title(win, animgif);if (resizable && !test_tiles) {// need to reposition the widgets (have been moved by setting resizable())if (canvas && canvas2) {canvas->resize(0, 0, W / 2, canvas->h());canvas2->resize(W / 2, 0, W / 2, canvas2->h());}else if (canvas) {canvas->resize(0, 0, animgif->canvas_w(), animgif->canvas_h());}}// fltk窗体禁止响应快捷键的窗体size缩放win->init_sizes(); // IMPORTANT: otherwise weird things happen at Ctrl+/- scaling}else {delete win;return 0;}if (debug >= 3) {// open each frame in a separate windowfor (int i = 0; i < animgif->frames(); i++) {char buf[200];snprintf(buf, sizeof(buf), "Frame #%d", i + 1);Fl_Double_Window* win = new Fl_Double_Window(animgif->w(), animgif->h());win->copy_tooltip(buf);win->copy_label(buf);win->color(BackGroundColor);int w = animgif->image(i)->w();int h = animgif->image(i)->h();// in 'optimize_mem' mode frames must be offsetted to canvasint x = (w == animgif->w() && h == animgif->h()) ? 0 : animgif->frame_x(i);int y = (w == animgif->w() && h == animgif->h()) ? 0 : animgif->frame_y(i);Fl_Box* b = new Fl_Box(x, y, w, h);// get the frame imageb->image(animgif->image(i));win->end();win->show();}}return win;
}#include <FL/filename.H>
bool openDirectory(const char* dir, char* flags) {dirent** list;int nbr_of_files = fl_filename_list(dir, &list, fl_alphasort);if (nbr_of_files <= 0)return false;int cnt = 0;for (int i = 0; i < nbr_of_files; i++) {char buf[512];const char* name = list[i]->d_name;if (!strcmp(name, ".") || !strcmp(name, "..")) continue;const char* p = strstr(name, ".gif");if (!p) p = strstr(name, ".GIF");if (!p) continue;if (*(p + 4)) continue; // is no extension!snprintf(buf, sizeof(buf), "%s/%s", dir, name);if (strstr(name, "debug"))  // hack: when name contains 'debug' open single framesstrcat(flags, "d");if (openFile(buf, flags, cnt == 0))cnt++;}return cnt != 0;
}static void change_speed(double delta) {Fl_Widget* below = Fl::belowmouse();if (below && below->image()) {Fl_Anim_GIF_Image* animgif = 0;// Q: is there a way to determine Fl_Tiled_Image without using dynamic cast?Fl_Tiled_Image* tiled = dynamic_cast<Fl_Tiled_Image*>(below->image());animgif = tiled ?dynamic_cast<Fl_Anim_GIF_Image*>(tiled->image()) :dynamic_cast<Fl_Anim_GIF_Image*>(below->image());if (animgif && animgif->playing()) {double speed = animgif->speed();if (!delta) speed = 1.;else speed += delta;if (speed < 0.1) speed = 0.1;if (speed > 10) speed = 10;animgif->speed(speed);set_title(below->window(), animgif);}}
}static int events(int event) {if (event == FL_SHORTCUT) {if (Fl::event_key() == '+')change_speed(0.1);else if (Fl::event_key() == '-')change_speed(-0.1);else if (Fl::event_key() == '0')change_speed(0);elsereturn 0;return 1;}return 0;
}static const char testsuite[] = "testsuite";int fl_demo_main(int argc, char* argv[]) {// 注册图像文件类型判断回调fl_register_images();// 事件回调的注册Fl::add_handler(events);char* openFlags = (char*)calloc(1024, 1);if (argc > 1) {// started with argumemtsif (strstr(argv[1], "-h")) {printf("Usage:\n""   -t [directory] [-{flags}] open all files in directory (default name: %s) [with options]\n""   filename [-{flags}] open single file [with options] \n""   No arguments open a fileselector\n""   {flags} can be: d=debug mode, u=uncached, D=desaturated, A=color averaged, T=tiled\n""                   m=minimal update, r[scale factor]=resize by 'scale factor'\n""   Use keys '+'/'-/0' to change speed of the active image (belowmouse).\n", testsuite);exit(1);}for (int i = 1; i < argc; i++) {if (argv[i][0] == '-')strcat(openFlags, &argv[i][1]);}if (strchr(openFlags, 't')) { // open all GIF-files in a given directoryconst char* dir = testsuite;for (int i = 2; i < argc; i++)if (argv[i][0] != '-')dir = argv[i];openDirectory(dir, openFlags);printf("Summary: good=%d, bad=%d, frames=%d\n", g_good_count, g_bad_count, g_frame_count);}else { // open given file(s)for (int i = 1; i < argc; i++)if (argv[i][0] != '-')openFile(argv[i], openFlags, strchr(openFlags, 'd'));}}else {// started without arguments: choose file// GIF图像显示为图片或动画的标志设置Fl_GIF_Image::animate = true; // create animated shared .GIF images (e.g. file chooser)while (1) {Fl::add_timeout(RedrawDelay, cb_forced_redraw); // animate images in chooser// 文件选择器UI的调用和返回// 用户选择通过文件选择器选择的文件,有可能不是指定尾缀的文件类型const char* filename = fl_file_chooser("Select a GIF image file", "*.{gif,GIF}", NULL);// 超时回调的移除Fl::remove_timeout(cb_forced_redraw);if (!filename)break;Fl_Window* win = openFile(filename, openFlags);// 等待当前窗体正常结束Fl::run();// delete last window (which is now just hidden) to test destructors// NOTE: it is essential that *before* doing this also the//       animated image is destroyed, otherwise it will crash//       because it's canvas will be gone.//       In order to keep this demo simple, the adress of the//       Fl_Anim_GIF_Image has been stored in the window's user_data.//       In a real-life application you will probably store//       it somewhere in the window's or canvas' object and destroy//       the image in the window's or canvas' destructor.if (win && win->user_data())delete ((Fl_Anim_GIF_Image*)win->user_data());delete win;}}return Fl::run();
}

END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/893963.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣hot100-->滑动窗口、贪心

你好呀&#xff0c;欢迎来到 Dong雨 的技术小栈 &#x1f331; 在这里&#xff0c;我们一同探索代码的奥秘&#xff0c;感受技术的魅力 ✨。 &#x1f449; 我的小世界&#xff1a;Dong雨 &#x1f4cc; 分享我的学习旅程 &#x1f6e0;️ 提供贴心的实用工具 &#x1f4a1; 记…

【蓝桥杯嵌入式入门与进阶】2.与开发板之间破冰:初始开发板和原理图2

个人主页&#xff1a;Icomi 专栏地址&#xff1a;蓝桥杯嵌入式组入门与进阶 大家好&#xff0c;我是一颗米&#xff0c;本篇专栏旨在帮助大家从0开始入门蓝桥杯并且进阶&#xff0c;若对本系列文章感兴趣&#xff0c;欢迎订阅我的专栏&#xff0c;我将持续更新&#xff0c;祝你…

Spring Boot - 数据库集成02 - 集成JPA

集成JPA 文章目录 集成JPA一&#xff1a;JPA概述1&#xff1a;JPA & JDBC2&#xff1a;JPA规范3&#xff1a;JPA的状态和转换关系 二&#xff1a;Spring data JPA1&#xff1a;JPA_repository1.1&#xff1a;CurdRepostory<T, ID>1.2&#xff1a;PagingAndSortingRep…

从ai产品推荐到利用cursor快速掌握一个开源项目再到langchain手搓一个Text2Sql agent

目录 0. 经验分享&#xff1a;产品推荐 1. 经验分享&#xff1a;提示词优化 2. 经验分享&#xff1a;使用cursor 阅读一篇文章 3. 经验分享&#xff1a;使用cursor 阅读一个完全陌生的开源项目 4. 经验分享&#xff1a;手搓一个text2sql agent &#xff08;使用langchain l…

【Java-数据结构】Java 链表面试题下 “最后一公里”:解决复杂链表问题的致胜法宝

我的个人主页 我的专栏&#xff1a;Java-数据结构&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞❤ 收藏❤ 引言&#xff1a; Java链表&#xff0c;看似简单的链式结构&#xff0c;却蕴含着诸多有趣的特性与奥秘&#xff0c;等待我们去挖掘。它就像一…

智慧园区系统的类型及其在企业管理效率提升中的关键作用解析

内容概要 在智慧园区的建设中&#xff0c;各类系统的采用是提升管理效率的关键所在。快鲸智慧园区(楼宇)管理系统&#xff0c;通过其全面数字化的管理手段&#xff0c;已经成为了企业管理的新标杆。这一系统能够有效整合租赁管理、资产管理、招商管理和物业管理等功能&#xf…

多级缓存(亿级并发解决方案)

多级缓存&#xff08;亿级流量&#xff08;并发&#xff09;的缓存方案&#xff09; 传统缓存的问题 传统缓存是请求到达tomcat后&#xff0c;先查询redis&#xff0c;如果未命中则查询数据库&#xff0c;问题如下&#xff1a; &#xff08;1&#xff09;请求要经过tomcat处…

第27篇 基于ARM A9处理器用C语言实现中断<三>

Q&#xff1a;基于ARM A9处理器怎样设计C语言工程&#xff0c;同时使用按键中断和定时器中断在红色LED上计数&#xff1f; A&#xff1a;基本原理&#xff1a;设置HPS Timer 0和按键中断源&#xff0c;主程序调用set_A9_IRQ_stack( )函数设置中断模式的ARM堆栈指针&#xff0c…

C++ 中用于控制输出格式的操纵符——setw 、setfill、setprecision、fixed

目录 四种操纵符简要介绍 setprecision基本用法 setfill的基本用法 fixed的基本用法 setw基本用法 以下是一些常见的用法和示例&#xff1a; 1. 设置字段宽度和填充字符 2. 设置字段宽度和对齐方式 3. 设置字段宽度和精度 4. 设置字段宽度和填充字符&#xff0c;结合…

【1.安装ubuntu22.04】

目录 参考文章链接电脑参数安装过程准备查看/更改引导方式查看/更改磁盘的分区格式关闭BitLocker加密压缩分区关闭独显直连制作Ubuntu安装盘下载镜像制作启动盘 进入BIOS模式进行设置Secure Boot引导项顺序try or install ubuntu 进入安装分区启动引导器个人信息和重启 参考文章…

代码随想录算法【Day34】

Day34 62.不同路径 思路 第一种&#xff1a;深搜 -> 超时 第二种&#xff1a;动态规划 第三种&#xff1a;数论 动态规划代码如下&#xff1a; class Solution { public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m, vector<int>(n,…

计算机毕业设计PySpark+hive招聘推荐系统 职位用户画像推荐系统 招聘数据分析 招聘爬虫 数据仓库 Django Vue.js Hadoop

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

强化学习数学原理(三)——迭代算法

一、值迭代过程 上面是贝尔曼最优公式&#xff0c;之前我们说过&#xff0c;f(v)v&#xff0c;贝尔曼公式是满足contraction mapping theorem的&#xff0c;能够求解除它最优的策略和最优的state value&#xff0c;我们需要通过一个最优v*&#xff0c;这个v*来计算状态pi*&…

AI 浪潮席卷中国年,开启科技新春新纪元

在这博主提前祝大家蛇年快乐呀&#xff01;&#xff01;&#xff01; 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;其影响力已经渗透到社会生活的方方面面。在中国传统节日 —— 春节期间&#xff0c;AI 技术也展现出了巨大的潜力&#xff0c;为中国年带…

vim的特殊模式-可视化模式

可视化模式&#xff1a;按 v进入可视化模式 选中 y复制 d剪切/删除 可视化块模式: ctrlv 选中 y复制 d剪切/删除 示例&#xff1a; &#xff08;vim可视化模式的进阶使用&#xff1a;vim可视化模式的进阶操作-CSDN博客&#xff09;

sunrays-framework配置重构

文章目录 1.common-log4j2-starter1.目录结构2.Log4j2Properties.java 新增两个属性3.Log4j2AutoConfiguration.java 条件注入LogAspect4.ApplicationEnvironmentPreparedListener.java 从Log4j2Properties.java中定义的配置读取信息 2.common-minio-starter1.MinioProperties.…

相互作用感知的蛋白-小分子对接模型 - Interformer 评测

Interformer 是一个应用于分子对接和亲和力预测的深度学习模型&#xff0c;基于 Graph-Transdormer 架构的模型&#xff0c;利用相互作用&#xff08;氢键、疏水&#xff09;感知的混合密度网络&#xff08;interaction-aware mixture den sity network&#xff0c; MDN&#x…

Ceisum无人机巡检直播视频投射

接上次的视频投影&#xff0c;Leader告诉我这个视频投影要用在两个地方&#xff0c;一个是我原先写的轨迹回放那里&#xff0c;另一个在无人机起飞后的地图回显&#xff0c;要实时播放无人机拍摄的视频&#xff0c;还要能转镜头&#xff0c;让我把这个也接一下。 我的天&#x…

【漫话机器学习系列】065.梯度(Gradient)

梯度&#xff08;Gradient&#xff09; 在数学和机器学习中&#xff0c;梯度是一个向量&#xff0c;用来表示函数在某一点的变化方向和变化率。它是多变量函数的一阶偏导数的组合。 梯度的定义 设有一个标量函数 &#xff0c;它对 ​ 是可微的&#xff0c;则该函数在某一点的…

基于SpringBoot多数据源解决方案

最近在学习SpringBoot的时候&#xff0c;需要同时用两个不同的数据库连接服务&#xff0c;在网上学习了之后&#xff0c;下文以连接一个MySQL数据库和一个SqlServer数据库为例。 配置数据源连接信息 在配置文件中&#xff0c;配置对应的数据库连接信息&#xff0c;相比于单数…