FLTK - FLTK1.4.1 - demo - animgifimage-play
文章目录
- FLTK - FLTK1.4.1 - demo - animgifimage-play
- 概述
- 笔记
- END
FLTK - FLTK1.4.1 - demo - animgifimage-play
概述
看的官方demo越多,在每个新demo中能看到的新增知识点越少。这是好事。
不可能一次将细节都记住,只要知道每个官方demo能干啥,有些啥新增知识点,这就够了。
就像一本好书一样,至少也要看几遍。
再不济,翻一遍,知道有啥,等需要的时候,再来拿。
// 播放多张gif, 并能控制(缩放,速度,正反向播放, 下一张图片)
// 新增知识点
// gif图像切换当前帧
// 所有的新窗体,都是作为当前窗体的子窗体存在, 所以fltk的窗体不用指定父窗体是谁
笔记
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR lpCmdLine,_In_ int nCmdShow)
{UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);char* argv[4] = {};argv[0] = (char*)"app-name";argv[1] = (char*)"003_ over_rest.gif";argv[2] = (char*)"004_no_contact.gif";argv[3] = (char*)"005_bonded.gif";return fl_demo_main(4, argv);// return 0;
}
// FLTK - FLTK1.4.1 - demo - animgifimage-play// 播放多张gif, 并能控制(缩放,速度,正反向播放, 下一张图片)// 新增知识点
// gif图像切换当前帧
// 所有的新窗体,都是作为当前窗体的子窗体存在, 所以fltk的窗体不用指定父窗体是谁#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//
// Demonstrates how to play an animated GIF file
// under application control frame by frame if
// this is needed.
// Also demonstrates how to use a single animation
// object to load multiple animations.
//
// animgifimage <file> [-r] [-s speed_factor]
//
// Multiple files can be specified e.g. testsuite/*
//
// Use keys '+'/'-'/Enter to change speed, ' ' to pause.
// Right key changes to next frame in paused mode.
// 'n' changes to next file, 'r' toggles reverse play.
//
#include <FL/Fl_Anim_GIF_Image.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl.H>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>static double speed_factor = 1.; // slow down/speed up playback by factor
static bool reverse = false; // true = play animation backwards
static bool paused = false; // flag for paused animation
static bool frame_info = true; // flag to update current frame info in title
static Fl_Anim_GIF_Image animgif; // the animation object
static char** Argv = 0; // copy of main() argv[]
static int Argc = 0; // copy of main() argc
static int current_arg = 0; // current index in argv[]static int next_arg() {while (1) {current_arg++;if (current_arg >= Argc) {current_arg = 1;}if (Argv[current_arg]) break;}return current_arg;
}static const char* next_file() {while (Argv[next_arg()][0] == '-');return Argv[current_arg];
}static void set_title() {char buf[200];char fi[50];if (frame_info)snprintf(fi, sizeof(fi), "frame %d/%d", animgif.frame() + 1, animgif.frames());elsesnprintf(fi, sizeof(fi), "%d frames", animgif.frames());snprintf(buf, sizeof(buf), "%s (%s) x %3.2f %s%s",Argv[current_arg], fi,speed_factor, reverse ? "reverse" : "",paused ? " PAUSED" : "");Fl::first_window()->copy_label(buf);
}static void cb_anim(void* d_) {Fl_Anim_GIF_Image* animgif = (Fl_Anim_GIF_Image*)d_;int frame{ animgif->frame() };// switch to next/previous frameif (reverse) {animgif->canvas()->window()->redraw();frame--;if (frame < 0) {frame = animgif->frames() - 1;}}else {frame++;if (frame >= animgif->frames()) {frame = 0;}}// set the frame (and update canvas)// gif图像切换当前帧animgif->frame(frame);// setup timer for next frameif (!paused && animgif->delay(frame)) {Fl::repeat_timeout(animgif->delay(frame) / speed_factor, cb_anim, d_);}if (frame_info)set_title();
}static void next_frame() {cb_anim(&animgif);
}static void toggle_pause() {paused = !paused;set_title();if (paused)Fl::remove_timeout(cb_anim, &animgif);elsenext_frame();set_title();
}static void toggle_info() {frame_info = !frame_info;set_title();
}static void toggle_reverse() {reverse = !reverse;set_title();
}static void zoom(bool out) {int W = animgif.w();int H = animgif.h();// Note: deliberately no range check (use key 'N' to reset)static const double f = 1.05;// 设置图像在画布上的大小if (out)animgif.resize(int(W / f), int(H / f));elseanimgif.resize(int(f * W), int(f * H));
}static void change_speed(int dir_) {if (dir_ > 0) {speed_factor += (speed_factor < 1) ? 0.01 : 0.1;if (speed_factor > 100)speed_factor = 100.;}else if (dir_ < 0) {speed_factor -= (speed_factor > 1) ? 0.1 : 0.01;if (speed_factor < 0.01)speed_factor = 0.01;}else {speed_factor = 1.;}set_title();
}static void load_next() {Fl::remove_timeout(cb_anim, &animgif);paused = false;animgif.load(next_file());animgif.canvas()->window()->redraw();// check if loading succeededprintf("valid: %d frames: %d\n", animgif.valid(), animgif.frames());if (animgif.valid()) {printf("play '%s'%s with %3.2f x speed\n", animgif.name(),(reverse ? " reverse" : ""), speed_factor);animgif.frame(reverse ? animgif.frames() - 1 : 0);// setup first timeout, but check for zero-delay (normal GIF)!if (animgif.delay(animgif.frame())) {Fl::add_timeout(animgif.delay(animgif.frame()) / speed_factor, cb_anim, &animgif);}}set_title();
}static int events(int event_) {if (event_ == FL_SHORTCUT && Fl::first_window()) {switch (Fl::event_key()) {case '+': change_speed(1); break;case '-': change_speed(-1); break;case FL_Enter: change_speed(0); break;case 'n': load_next(); break;case 'z': zoom(Fl::event_shift()); break;case 'i': toggle_info(); break; // Note: this can raise cpu usage considerably!case 'r': toggle_reverse(); break;case ' ': toggle_pause(); break;case FL_Right:if (paused && Fl::get_key(FL_Right)) next_frame();break;default:return 0;}Fl::first_window()->redraw();return 1;}return 0;
}int fl_demo_main(int argc, char* argv[]) {// setup play parameters from argsArgv = argv;Argc = argc;int n = 0;for (int i = 1; i < argc; i++) {if (!strcmp(argv[i], "-r"))reverse = !reverse;else if (!strcmp(argv[i], "-s") && i + 1 < argc) {i++;speed_factor = atof(argv[i]);argv[i] = 0;}else if (argv[i][0] != '-') {n++;continue;}else {printf("Invalid argument: '%s'\n", argv[i]);exit(1);}}if (!n) {fprintf(stderr, "Test program for application controlled GIF animation.\n");fprintf(stderr, "Please specify one or more image files!\n");exit(0);}if (speed_factor < 0.01 || speed_factor > 100)speed_factor = 1.;Fl_Double_Window win(800, 600);// prepare a canvas for the animation// (we want to show it in the center of the window)Fl_Box canvas(0, 0, win.w(), win.h());// 所有的新窗体,都是作为当前窗体的子窗体存在, 所以fltk的窗体不用指定父窗体是谁Fl_Box help(0, win.h() - 20, win.w(), 20, "Keys: N=next file, I=toggle info, R=play reverse, +/-/Enter/Space=change speed, Z=Zoom");win.resizable(win);win.end();win.show();Fl::add_handler(events);// use the 'DONT_RESIZE_CANVAS' flag to tell the animation// not to change the canvas size (which is the default).unsigned short flags = Fl_Anim_GIF_Image::DONT_RESIZE_CANVAS;// flags |= Fl_Anim_GIF_Image::DEBUG_FLAG|Fl_Anim_GIF_Image::LOG_FLAG;animgif.canvas(&canvas, flags);load_next();return Fl::run();
}
END
相关文章:
FLTK - FLTK1.4.1 - demo - animgifimage-play
文章目录 FLTK - FLTK1.4.1 - demo - animgifimage-play概述笔记END FLTK - FLTK1.4.1 - demo - animgifimage-play 概述 看的官方demo越多,在每个新demo中能看到的新增知识点越少。这是好事。 不可能一次将细节都记住,只要知道每个官方demo能干啥&…...
2024年除夕
多少年前的除夕,一如今天这样的除夕;多少年后的除夕,也一如多少年前的除夕。 无数个这样的除夕下午,我打开电脑,望着窗外安静的小区,车声渐渐稀疏的马路,想写下一些新的感受时,多少…...
如何实现滑动删除功能
文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了GestureDetector Widget相关的内容,本章回中将介绍Dismissible Widget.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在这里介绍的Dismissible是一个事件响应Widget,它和GestureDetector类…...
golang通过AutoMigrate方法自动创建table详解
一.AutoMigrate介绍 1.介绍 在 Go 语言中,GORM支持Migration特性,支持根据Go Struct结构自动生成对应的表结构,使用 GORM ORM 库的 AutoMigrate 方法可以自动创建数据库表,确保数据库结构与定义的模型结构一致。AutoMigrate 方法非常方便&am…...
JAVA:利用 Content Negotiation 实现多样式响应格式的技术指南
1、简述 Content Negotiation(内容协商) 是 RESTful 服务的重要特性,允许客户端和服务器根据请求的不同特性动态选择适合的响应格式。它是一种在 HTTP 协议中实现的机制,通过它,服务器能够根据客户端需求返回适合的内…...
Python 函数魔法书:基础、范例、避坑、测验与项目实战
Python 函数魔法书:基础、范例、避坑、测验与项目实战 内容简介 本系列文章是为 Python3 学习者精心设计的一套全面、实用的学习指南,旨在帮助读者从基础入门到项目实战,全面提升编程能力。文章结构由 5 个版块组成,内容层层递进…...
OpenBMC:编译
1.安装依赖 OpenBMC是基于Yocto搭建的,基于不同的OS预先需要安装的依赖包和工具,清参考: 1 System Requirements — The Yocto Project 5.1.999 documentation 2.下载代码 OpenBMC的源码位于: openbmc/openbmc: OpenBMC Distri…...
Effective Objective-C 2.0 读书笔记—— objc_msgSend
Effective Objective-C 2.0 读书笔记—— objc_msgSend 文章目录 Effective Objective-C 2.0 读书笔记—— objc_msgSend引入——静态绑定和动态绑定OC之中动态绑定的实现方法签名方法列表 其他方法objc_msgSend_stretobjc_msgSend_fpretobjc_msgSendSuper 尾调用优化总结参考文…...
使用EVE-NG-锐捷实现OSPF
一、OSPF基础知识 Open shortest Path First(OSPF)开放式最短路径优先协议 1.OSPF的关系状态 (1)邻居关系(TWO-WAY) 只发送hello包不发送LSA包(链路状态通告包) (2)邻接关系(FULL) OSPF设备与设备之间相互建立OSPF关系,初始为邻居关系(TWO-WAY)状态࿰…...
电商系统-用户认证(三)基于公钥解析JWT令牌
一、 基于私钥生成jwt令牌 步骤: 导入认证服务 将shangcheng_user_auth工程导入到项目中去,如下图 启动eureka,再启动认证服务 3) 认证服务中创建测试类 public class CreateJwtTest { /**** 创建令牌测试*/Testpublic voi…...
【论文投稿-第八届智能制造与自动化学术会议(IMA 2025)】HTML, CSS, JavaScript:三者的联系与区别
大会官网:www.icamima.org 目录 前言 一、HTML(超文本标记语言):网页的骨架 HTML 的作用: 例子: 总结: 二、CSS(层叠样式表):网页的外观设计 CSS 的…...
Baklib赋能下的内容中台智能化推荐系统解析与展望
内容概要 在数字化时代,内容中台的智能化推荐系统正逐渐成为各类企业提升用户体验与运营效率的重要工具。该系统通过集成和分析大量用户数据及内容信息,能够实现精准的个性化推荐,为用户提供最相关的内容。 以下是内容中台智能化推荐系统的…...
2024年记 | 凛冬将至
放弃幻想,准备斗争! 考研or就业? 上大学以来,考研上名校在我的心里一直是一颗种子,2024年初,当时的想法是考研和就业两手抓。买了张宇的高数现代,想要死磕! 也记了挺多笔记... 如果…...
虚幻基础08:组件接口
能帮到你的话,就给个赞吧 😘 文章目录 作用 作用 组件接口:可以直接调用对方的组件接口,而无需转换为actor。 实现对象间的通知。 A 通知 B 做什么。...
http3网站的设置(AI不会配,得人工配)
堡塔PHP项目中配置nginx1.26.0设置http3协议 # 文件所在服务器中的路径 /www/server/nginx/conf/nginx.confuser www www; worker_processes auto; error_log /www/wwwlogs/nginx_error.log crit; pid /www/server/nginx/logs/nginx.pid; worker_rlimit_nofile 512…...
数据分析系列--②RapidMiner导入数据和存储过程
一、下载数据 点击下载AssociationAnalysisData.xlsx数据集 二、导入数据 1. 在本地计算机中创建3个文件夹 2. 从本地选择.csv或.xlsx 三、界面说明 四、存储过程 将刚刚新建的过程存储到本地 Congratulations, you are done....
使用iis服务器模拟本地资源服务器unityaddressables热更新出错记录
editor中设置了using exculexing 模拟远程加载addressable可以实现资源热更新,build后的软件却没有成功。 iis服务器中mime中需要设置bundle的文件扩展名,时editor成功,build后失败 原因没有设置hash的扩展名,设置后editor和buil…...
Ubuntu x64下交叉编译ffmpeg、sdl2到目标架构为aarch64架构的系统(生成ffmpeg、ffprobe、ffplay)
一、编译SDL2-2.0.9 (1), ./configure --prefix/home/z/Desktop/sdl2 --enable-sharedyes --enable-nasmno --enable-audiono --enable-ossno --enable-alsano --enable-alsa-sharedno --enable-pulseaudiono --enable-pulseaudio-sharedno …...
进程通讯——类型和发展
进程常用交互方法如上...
深度学习:从基础到前沿
🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:Linux 🌹往期回顾🌹:【Linux】进程地址空间与虚拟地址空间 🔖流水不争,争的是滔滔不 一、深度学习的基础知…...
Node.js与MySQL模块结合:打造安全高效的用户信息管理系统
摘要 本文探讨使用Node.js构建前端项目并导入MySQL模块创建数据库连接对象的方法。文中讲解了共享数据库连接对象,定义SQL语句查询和更新用户信息(排除密码字段以保护隐私),以及根据用户ID更新基本信息、重置密码和更新头像的具体…...
【项目】基于Qt开发的音乐播放软件
目录 项目介绍 项目概述 界面开发 界面分析 创建工程 主界面布局设计 窗口主框架设计 界面美化 主窗口设定 添加图片资源 head处理 播放控制区处理 自定义控件 BtForm 推荐页面 自定义CommonPage 自定义ListItemBox 自定义MusicSlider 自定义VolumeTool 音…...
C语言,无法正常释放char*的空间
问题描述 #include <stdio.h> #include <stdio.h>const int STRSIZR 10;int main() {char *str (char *)malloc(STRSIZR*sizeof(char));str "string";printf("%s\n", str);free(str); } 乍一看,这块代码没有什么问题。直接书写…...
Promise.race
Promise.race 是 JavaScript 中 Promise 对象的一个静态方法,用于将多个 Promise 实例包装成一个新的 Promise 实例。这个新的 Promise 实例会在 最先完成(无论是 fulfilled 还是 rejected) 的 Promise 完成时完成,并返回该 Promi…...
@RestControllerAdvice 的作用
系列博客目录 文章目录 系列博客目录1.ControllerAdvice 有什么用主要功能 2.与 RestControllerAdvice 的区别3.苍穹外卖中的使用4.RestControllerAdvice可以指定范围吗(1)指定应用到某些包中的 RestController(2)指定应用到具有特…...
信息学奥赛一本通 1390:食物链【NOI2001】| 洛谷 P2024 [NOI2001] 食物链
【题目链接】 ybt 1390:食物链【NOI2001】 洛谷 P2024 [NOI2001] 食物链 【题目考点】 1. 种类并查集 2. 带权并查集 【解题思路】 解法1:种类并查集 已知有三类动物A、B、C。A吃B,B吃C,C吃A。 对于B类动物来说,…...
MATLAB中fetchOutputs函数用法
目录 语法 说明 示例 在后台运行函数 fetchOutputs函数的功能是从在后台运行的函数中检索结果。 语法 [Y1,...,Ym] fetchOutputs(F) [Y1,...,Ym] fetchOutputs(F,UniformOutputfalse) 说明 [Y1, ..., Ym] fetchOutputs(F) 从 Future 数组 F 中检索出 m 个结果。 F 中…...
数据可视化的图表
1.折线图反映了一段时间内事物连续的动态变化规律,适用于描述一个变量随另一个变量变化的趋势,通常用于绘制连续数据,适合数据点较多的情况。 2.散点图是以直角坐标系中各点的密集程度和变化趋势来表示两种现象间的相关关系,常用于显示和比较数值。当要在不考虑时间…...
简易CPU设计入门:控制总线的剩余信号(四)
项目代码下载 请大家首先准备好本项目所用的源代码。如果已经下载了,那就不用重复下载了。如果还没有下载,那么,请大家点击下方链接,来了解下载本项目的CPU源代码的方法。 CSDN文章:下载本项目代码 上述链接为本项目…...
基础IO(2)
基础IO(2) 理解“⼀切皆⽂件” ⾸先,在windows中是⽂件的东西,它们在linux中也是⽂件;其次⼀些在windows中不是⽂件的东西,⽐如进程、磁盘、显⽰器、键盘这样硬件设备也被抽象成了⽂件,你可以使…...
