当前位置: 首页 > news >正文

北京网站建设公司有哪些网页生成

北京网站建设公司有哪些,网页生成,7黄页网站建设,高仿id97网站模板我看到的所有例程,都把扩展部分的处理跳过了,而我的动画是有透明度的,这就导致解码后的图像在有透明色的像素部分,呈现了很多的黑点,或者闪白的情况出现。经过调试,终于成功。 文件格式 先了解一下GIF的文…

我看到的所有例程,都把扩展部分的处理跳过了,而我的动画是有透明度的,这就导致解码后的图像在有透明色的像素部分,呈现了很多的黑点,或者闪白的情况出现。经过调试,终于成功。

文件格式

先了解一下GIF的文件格式:

GIF文件格式说明 - 猛回头 - 博客园

扩展块的处理

// 扩展块解析if (currentImage.ExtensionBlockCount > 0) // 存在扩展块{switch (currentImage.ExtensionBlocks[0].Function){case CONTINUE_EXT_FUNC_CODE:case COMMENT_EXT_FUNC_CODE:     // 注释扩展块case PLAINTEXT_EXT_FUNC_CODE:   // 图形文本扩展块case APPLICATION_EXT_FUNC_CODE: // 应用程序扩展块break;case GRAPHICS_EXT_FUNC_CODE: // 图形控制扩展块{if (DGifExtensionToGCB(currentImage.ExtensionBlocks[0].ByteCount, currentImage.ExtensionBlocks[0].Bytes, &gcb) == GIF_ERROR){continue;}// 透明色索引值,如果没有透明色,该值为-1transparent_color = gcb.TransparentColor;// 延迟时间的单位为0.01秒,转换为微秒delay_us = gcb.DelayTime * 10 * 1000;}default:break;}}//转换//显示if (gcb.DisposalMode == DISPOSE_BACKGROUND) // 回复到背景色{memset(gif_buffer, fp->SBackGroundColor, size);}else if (gcb.DisposalMode == DISPOSE_PREVIOUS) // 回复到先前状态(上一帧){for (int i = 0; i < size; i++){prev_gif_buffer[i] = gif_buffer[i];}}

透明度处理

在有透明的的情况下,GIF图像转为RGB需要进行以下判断:

 // 颜色索引等于透明度索引,进行透明处理,这里直接跳过,保持原像素值(上一帧此索引位置的像素)不变if (color_index == transparent_index){rgb_index += 3;}else{// 将颜色项的红色分量写入输出缓冲区rgb[rgb_index++] = ColorMap->Colors[color_index].Red;// 将颜色项的绿色分量写入输出缓冲区rgb[rgb_index++] = ColorMap->Colors[color_index].Green;// 将颜色项的蓝色分量写入输出缓冲区rgb[rgb_index++] = ColorMap->Colors[color_index].Blue;}

如果使用了透明色,要确定在解析时,解析到这一个像素时,不要对这个值进行任何操作,跳过即可。跳过后,你会发现上一帧这个位置的图像又出现在这个位置,符合预期,显示正常。

全部代码

全部代码如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <giflib/gif_lib.h>int fd = 0;/** GIF图像转换为RGB888图像字节处理)* @name: Gif_To_Rgb888* @param {ColorMapObject} *ColorMap    颜色表* @param {uint8_t} *rgb                解码后的rgb图像(输出)* @param {GifByteType} *gif_buf        gif图像* @param {int} gif_width               gif图像宽度* @param {int} gif_height              gif图像高度* @param {int} transparent_index       gif透明度索引值* @return {*}*/
static void Gif_To_Rgb888(ColorMapObject *ColorMap, uint8_t *rgb, GifByteType *gif_buf, int gif_width, int gif_height, int transparent_index)
{int index_h = 0; // 循环变量,用于遍历图像的高度方向int index_w = 0; // 循环变量,用于遍历图像的宽度方向// 外层循环遍历图像的每一行for (index_h = 0; index_h < gif_height; index_h++){// rgb_buf数据位置索引int rgb_index = index_h * gif_width * 3;// 内层循环遍历当前行的每一个像素for (index_w = 0; index_w < gif_width; index_w++){// 如果存在颜色表,进行转换操作if (ColorMap){// 获取当前像素在GIF缓冲区中的索引int color_index = gif_buf[index_h * gif_width + index_w];// 颜色索引等于透明度索引,进行透明处理,这里直接跳过,保持原像素值(上一帧此索引位置的像素)不变if (color_index == transparent_index){rgb_index += 3;}else{// 将颜色项的红色分量写入输出缓冲区rgb[rgb_index++] = ColorMap->Colors[color_index].Red;// 将颜色项的绿色分量写入输出缓冲区rgb[rgb_index++] = ColorMap->Colors[color_index].Green;// 将颜色项的蓝色分量写入输出缓冲区rgb[rgb_index++] = ColorMap->Colors[color_index].Blue;}}}}
}/*** @name: Display_RGB_From_Buffer* @param {uint8_t} *buffer* @param {int} fb_fd* @param {int} xres* @param {int} yres* @return {*}*/
static void Display_RGB_From_Buffer(uint8_t *buffer, int gif_width, int gif_height)
{fd = open("/dev/fb0", O_RDWR);if (fd < 0){perror("设备文件打开失败");return;}// 屏幕分辨率,固定不变int screen_size = 480 * 800 * 4;char *fb_data = malloc(screen_size);memset(fb_data, 0, screen_size);for (int y = 0; y < gif_height; y++){for (int x = 0; x < gif_width; x++){uint8_t r = buffer[(y * gif_width + x) * 3 + 0];uint8_t g = buffer[(y * gif_width + x) * 3 + 1];uint8_t b = buffer[(y * gif_width + x) * 3 + 2];// 这个索引值是显示位置的变化,现在的显示位置是在屏幕的(50,50)int index = (y + 50) * 480 * 4 + (x + 50) * 4;fb_data[index + 0] = b;fb_data[index + 1] = g;fb_data[index + 2] = r;fb_data[index + 3] = 255;}}ssize_t bytes_written = write(fd, fb_data, screen_size);if (bytes_written != screen_size){perror("Error writing to framebuffer");}free(fb_data);close(fd);
}int GIF_Decode(char *file)
{int error;                  // 错误码int size = 0;               // GIF数据大小int transparent_color = -1; // 透明色索引int delay_us;               // 延时时间,单位微秒GifFileType *fp;                     // gif文件标识符GifByteType *gif_buffer = NULL;      // GIF数据GifByteType *prev_gif_buffer = NULL; // GIF上一帧数据GraphicsControlBlock gcb = {         // GIF图像控制块.DelayTime = 0,.DisposalMode = 0,.TransparentColor = -1,.UserInputFlag = 0};// 定义交错图像的读取偏移量和步长数组int InterlacedOffset[] = {0, 4, 2, 1};int InterlacedJumps[] = {8, 8, 4, 2};// 打开GIF文件fp = DGifOpenFileName(file, &error);if (fp == NULL){printf("打开GIF文件失败: %s\n", GifErrorString(error));return -1;}//  读取GIF文件的完整信息(一次性读取所有GIF信息,存放在fp结构体内)if (DGifSlurp(fp) == GIF_ERROR){printf("解析GIF详细信息错误: %s\n", GifErrorString(fp->Error));// 关闭GIF文件DGifCloseFile(fp, &error);return -1;}printf("GIF分辨率: %d*%d\n", fp->SWidth, fp->SHeight);printf("总帧数: %d\n", fp->ImageCount);// 内存空间申请、初始化size = fp->SWidth * fp->SHeight;uint8_t rgb[size * 3];memset(rgb, 0, sizeof(rgb));gif_buffer = (GifByteType *)malloc(size * sizeof(GifByteType));if (gif_buffer == NULL){printf("内存空间申请失败\n");DGifCloseFile(fp, &error);return -1;}prev_gif_buffer = (GifByteType *)malloc(size * sizeof(GifByteType));if (prev_gif_buffer == NULL){printf("内存空间申请失败\n");DGifCloseFile(fp, &error);return -1;}// 填充背景颜色for (int i = 0; i < size; i++){gif_buffer[i] = fp->SBackGroundColor;prev_gif_buffer[i] = fp->SBackGroundColor;}// 遍历读取到的每一帧图像数据进行处理for (int ImageNum = 0; ImageNum < fp->ImageCount; ImageNum++){// 当前图像的信息SavedImage currentImage = fp->SavedImages[ImageNum];// 获取图像的位置和尺寸信息int row = currentImage.ImageDesc.Top;       // 图像位置-行int col = currentImage.ImageDesc.Left;      // 图像位置-列int width = currentImage.ImageDesc.Width;   // 图像数据宽度int height = currentImage.ImageDesc.Height; // 图像数据高度// 检测是否超过逻辑屏幕边界if (currentImage.ImageDesc.Left + currentImage.ImageDesc.Width > fp->SWidth || currentImage.ImageDesc.Top + currentImage.ImageDesc.Height > fp->SHeight){printf("第%d帧图像超过了屏幕边界,无法解码.\n", ImageNum);continue;}// 如果图像是交错的if (currentImage.ImageDesc.Interlace){// 按照交错图像的读取方式逐行读取像素数据for (int iH = 0; iH < 4; iH++){for (int iW = row + InterlacedOffset[iH]; iW < row + height; iW += InterlacedJumps[iH]){// 计算当前像素在Buffer中的索引位置int index = (iW * fp->SWidth + col);for (int x = 0; x < width; x++){gif_buffer[index + x] = currentImage.RasterBits[(iW - row) * width + x];}}}}else{// 如果不是交错图像,则顺序读取像素数据for (int iH = 0; iH < height; iH++){// 计算当前像素在Buffer中的索引位置int index = ((row + iH) * fp->SWidth + col);for (int iW = 0; iW < width; iW++){gif_buffer[index + iW] = currentImage.RasterBits[iH * width + iW];}}}// 扩展块解析if (currentImage.ExtensionBlockCount > 0) // 存在扩展块{switch (currentImage.ExtensionBlocks[0].Function){case CONTINUE_EXT_FUNC_CODE:case COMMENT_EXT_FUNC_CODE:     // 注释扩展块case PLAINTEXT_EXT_FUNC_CODE:   // 图形文本扩展块case APPLICATION_EXT_FUNC_CODE: // 应用程序扩展块break;case GRAPHICS_EXT_FUNC_CODE: // 图形控制扩展块{if (DGifExtensionToGCB(currentImage.ExtensionBlocks[0].ByteCount, currentImage.ExtensionBlocks[0].Bytes, &gcb) == GIF_ERROR){continue;}// 透明色索引值,如果没有透明色,该值为-1transparent_color = gcb.TransparentColor;// 延迟时间的单位为0.01秒,转换为微秒delay_us = gcb.DelayTime * 10 * 1000;}default:break;}}// 获取颜色映射表,如果没有颜色映射表则退出,有局部颜色表先用局部颜色表,否则使用全局颜色表ColorMapObject *colorMap = (currentImage.ImageDesc.ColorMap ? currentImage.ImageDesc.ColorMap : fp->SColorMap);if (colorMap == NULL){continue;}// 将 GIF 图像数据转换为 RGB888 格式Gif_To_Rgb888(colorMap, rgb, gif_buffer, fp->SWidth, fp->SHeight, transparent_color);#if 1// LCD显示解码后的图像Display_RGB_From_Buffer(rgb, fp->SWidth, fp->SHeight);// 帧间隔时间usleep(delay_us);
#endifif (gcb.DisposalMode == DISPOSE_BACKGROUND) // 回复到背景色{memset(gif_buffer, fp->SBackGroundColor, size);}else if (gcb.DisposalMode == DISPOSE_PREVIOUS) // 回复到先前状态(上一帧){for (int i = 0; i < size; i++){prev_gif_buffer[i] = gif_buffer[i];}}}// 释放为Buffer分配的内存空间free(gif_buffer);free(prev_gif_buffer);// 关闭GIF文件,释放资源DGifCloseFile(fp, &error);return 0;
}

http://www.hkea.cn/news/297767/

相关文章:

  • 品牌推广网站怎样做百度手机助手苹果版
  • 武汉工业网站制作百度人工服务热线24小时
  • 新闻头条最新消息今日头条站长之家seo综合
  • app与网站宁波seo网络推广渠道介绍
  • 国外学做咖啡的网站百度高级搜索网址
  • 建网站开源代码游戏推广怎么找玩家
  • 莱州哪里有做网站的浙江网站建设平台
  • ps网站设计与制作免费推广seo
  • 网站查询功能怎么做关键词搜索量怎么查
  • 付费网站推广网站优化包括哪些内容
  • 在日本做色情网站广州seo外包
  • 最棒的网站建设考研最靠谱的培训机构
  • 广州建设企业网站黑河seo
  • 招商网站建设性价比高seo排名优化的
  • 产品网站怎么做的长沙正规关键词优化价格从优
  • 怎样查询江西省城乡建设厅网站杭州seo网
  • 网站建设空间是指什么软件网站优化最为重要的内容是
  • 做美工要开通什么网站的会员呢新网站友链
  • 网站集约化建设推进情况推广app赚钱
  • 番禺大石做网站域名污染查询网站
  • 长沙市在建工程项目免费seo快速排名工具
  • 南宁定制网站制作电话图片外链生成工具
  • 哪些网站做的海报比较高大上百度客服电话是多少
  • 菏泽网站建设电话常州seo外包
  • 做木皮的网站裂变营销五种模式十六种方法
  • 精美 企业网站模板微信软文推广怎么做
  • 怎么建立一个网站里面可以查询资料百度权重域名
  • 网站建设顺序镇江交叉口优化
  • 低价企业网站搭建软文新闻发布网站
  • 创造与魔法官方网站做自己喜欢的事seo视频