zoukankan      html  css  js  c++  java
  • 音视频入门-02-RGB拼图

    * 音视频入门文章目录 *

    图片 & 像素点 & RGB

    平时浏览的图片看不出像素点:

    image-demo

    图片放大时,可以看出图片是一个个像素点组成的:

    image-demo-pixel

    每个像素点的颜色可以用 RGB 表示:

    image-demo-pixel-rgb

    RGB 拼图

    既然图片是像素点组成的,而像素点的颜色可以用 RGB 来表示,那我们可以用 RGB 来拼出自己的图片!

    1. 设定目标

    这是我们想要使用 RGB 像素点拼出来的图片:

    image-demo-rainbow

    彩虹的颜色:

    颜色名 RGB 十六进制 RGB24 二进制
    255, 0, 0 0XFF0000 11111111 00000000 00000000
    255, 165, 0 0XFFA500 11111111 10100101 00000000
    255, 255, 0 0XFFFF00 11111111 11111111 00000000
    绿 0, 255, 0 0X00FF00 00000000 11111111 00000000
    0, 127, 255 0X007FFF 00000000 01111111 11111111
    0, 0, 255 0X0000FF 00000000 00000000 11111111
    139, 0, 255 0X8B00FF 10001011 00000000 11111111

    2. 分析实现思路

    用 RGB24 格式表示像素颜色值,每个像素用 24 比特位表示,占用三个字节。

    分辨率 7X7 彩虹图片像素排列:
    image-demo-rainbow-pixel-index

    分辨率 7X7 彩虹图片像素 RGB 二进制:
    image-demo-rainbow-pixel-binary

    7X7 只是为了分析方便,我们动手时要拼出 700X700 像素点的图片

    3. 动手实践

    将像素点的 RGB24 二进制存入文件:

    #include <stdio.h>
    
    // 彩虹的七种颜色
    u_int32_t rainbowColors[] = {
            0XFF0000, // 红
            0XFFA500, // 橙
            0XFFFF00, // 黄
            0X00FF00, // 绿
            0X007FFF, // 青
            0X0000FF, // 蓝
            0X8B00FF  // 紫
    };
    
    void writeRainbow(char *outputFile, int width, int height) {
    
        // 打开文件
        FILE *rgbFile = fopen(outputFile, "wb+");
        for (int i = 0; i < width; ++i) {
            // 当前颜色
            u_int32_t currentColor = 0X000000;
            if(i < 100) {
                // 前 100 行 红色
                currentColor = rainbowColors[0];
            } else if(i < 200) {
                // 100-200 行 橙色
                currentColor = rainbowColors[1];
            } else if(i < 300) {
                // 200-300 行 黄色
                currentColor = rainbowColors[2];
            } else if(i < 400) {
                // 300-400 行 绿色
                currentColor = rainbowColors[3];
            } else if(i < 500) {
                // 400-500 行 青色
                currentColor = rainbowColors[4];
            } else if(i < 600) {
                // 500-600 行 蓝色
                currentColor = rainbowColors[5];
            } else if(i < 700) {
                // 600-700 行 紫色
                currentColor = rainbowColors[6];
            }
            // 当前颜色 R 分量
            u_int8_t R = (currentColor & 0xFF0000) >> 16;
            // 当前颜色 G 分量
            u_int8_t G = (currentColor & 0x00FF00) >> 8;
            // 当前颜色 B 分量
            u_int8_t B = currentColor & 0x0000FF;
            for (int j = 0; j < height; ++j) {
                // 按顺序写入一个像素 RGB24 到文件中
                fputc(R, rgbFile);
                fputc(G, rgbFile);
                fputc(B, rgbFile);
            }
        }
    
        // 关闭文件
        fclose(rgbFile);
    }
    
    int main() {
        writeRainbow("/Users/staff/Desktop/rainbow-700x700.rgb24", 700, 700);
        return 0;
    }
    

    运行上面的代码,将会生成 rainbow-700x700.rgb24 文件

    检查生成的文件

    • 700X700=490000 个像素点
    • 每个像素点颜色用 RGB24 编码表示,每个像素点用 24 比特位表示,占 3 个字节
    • 490000 X 3 = 1470000 字节(B)
    $ cd Desktop
    $ ls -al rainbow-700x700.rgb24
    -rw-r--r--  1 staff  staff  1470000  9 12 18:17 rainbow-700x700.rgb24
    

    感觉生成了正确的 rgb24 格式的图片。

    确认 RGB24 文件正确性

    要确认生成的 rgb24 格式的图片是正确的,最直接的方式就是使用图片查看软件打开。但是,普通的图片查看软件都不支持 rgb24 这种格式。这时就要用专业的多媒体框架 FFmpeg 了。

    下载 ffplay 工具

    FFmpeg 工具下载

    根据自己的系统,下载 FFmpeg Static 工具包。

    这里拿 macOS 为例:

    $ ll
    total 163968
    -rw-r--r--@ 1 staff  staff    66M  9 12 20:43 ffmpeg-4.2-macos64-static.zip
    
    # 解压压缩包
    $ unzip ffmpeg-4.2-macos64-static.zip
    
    $ cd ffmpeg-4.2-macos64-static
    $ ll
    total 88
    -rw-r--r--@  1 staff  staff    35K  8  8 14:26 LICENSE.txt
    -rw-r--r--@  1 staff  staff   4.0K  8  8 14:26 README.txt
    drwxr-xr-x@  5 staff  staff   160B  8  8 14:26 bin
    drwxr-xr-x@ 35 staff  staff   1.1K  8  8 14:26 doc
    drwxr-xr-x@  8 staff  staff   256B  8  8 14:26 presets
    $ cd bin
    $ ll
    total 394000
    -rwxr-xr-x@ 1 staff  staff    64M  8  8 14:26 ffmpeg
    -rwxr-xr-x@ 1 staff  staff    64M  8  8 14:26 ffplay
    -rwxr-xr-x@ 1 staff  staff    64M  8  8 14:26 ffprobe
    
    # 测试执行 ffplay 命令
    $ ./ffplay
    ffplay version 4.2 Copyright (c) 2003-2019 the FFmpeg developers
      built with Apple LLVM version 10.0.1 (clang-1001.0.46.4)
      configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-appkit --enable-avfoundation --enable-coreimage --enable-audiotoolbox
      libavutil      56. 31.100 / 56. 31.100
      libavcodec     58. 54.100 / 58. 54.100
      libavformat    58. 29.100 / 58. 29.100
      libavdevice    58.  8.100 / 58.  8.100
      libavfilter     7. 57.100 /  7. 57.100
      libswscale      5.  5.100 /  5.  5.100
      libswresample   3.  5.100 /  3.  5.100
      libpostproc    55.  5.100 / 55.  5.100
    Simple media player
    usage: ffplay [options] input_file
    
    An input file must be specified
    Use -h to get full help or, even better, run 'man ffplay'
    

    使用 ffplay 打开 rgb24 图片

    ffplay -f rawvideo -pixel_format rgb24 -s 700x700 rainbow-700x700.rgb24
    
    # -pixel_format rgb24 指定像素格式 rgb24
    # -s 700x700 指定图片分辨率 700x700
    

    预览:

    rgb24-preview

    Congratulations!

    成功用像素点拼出了一张图片!


    代码:
    rgb-pixel

    内容有误?联系作者:
    联系作者


  • 相关阅读:
    初始线程(相关理论)
    python并发编程之多进程2-(数据共享及进程池和回调函数)
    python并发编程之多进程1--(互斥锁与进程间的通信)
    Cpython支持的进程与线程
    网络编程之进程理论简介
    python之网络socket编程
    Gray码 (格雷码) 【二进制】
    [BZOJ 2350] [Poi2011] Party 【Special】
    [BZOJ 1033] [ZJOI2008] 杀蚂蚁antbuster 【模拟!】
    [BZOJ 3209] 花神的数论题 【数位统计】
  • 原文地址:https://www.cnblogs.com/binglingziyu/p/audio-video-basic-02-rgb-puzzle.html
Copyright © 2011-2022 走看看