zoukankan      html  css  js  c++  java
  • C语言中将0到1000的浮点数用强制指针类型转换的方式生成一幅图像

          搞过计算机图像的人都知道,图像中的每一个像素通常为一个整型数,它可以分成4个无符号的char类型,以表示其RGBA四个分量。一幅图像可以看做是一个二维整型数组。这里我会生成一个float数组,其数组大小为1000000,刚好1000*1000,数组内的浮点数的数值范围在0到1000.0之间,呈等差数组排列,相邻两数的差为0.001。然后将其每一个浮点数强制转化成一个整型数或三个unsigned char型,以决定像素的RGB三个通道分量,看看其生成的图像是什么样子。

          前几天写了一篇文章是在C语言中使用异或运算交换两个任意类型变量,引来某人的质疑,说什么“指针的强制类型转换有一定限制,不是你想怎么转就怎么转的,结果可能会出错的”。用这种莫须有的话来否定我的代码。为嘲笑他的无知,我特意写出这种用强制指针类型转换生成图像的算法。

    先上C代码:

    #include <iostream>
    #include <cmath>
    #include <cstdlib>
    
    #define DIM 1000
    
    void pixel_write(int,int);
    FILE *fp;
    
    int main()
    {
        fp = fopen("image.ppm","wb");
        if (!fp)
        {
            return -1;
        }
    
        fprintf(fp, "P6
    %d %d
    255
    ", DIM, DIM);
        for(int j=0;j<DIM;j++)
        {
            for(int i=0;i<DIM;i++)
            {
                pixel_write(i,j);
            }
        }
        fclose(fp);
    
        return 0;
    }
    
    void pixel_write(int i, int j)
    {
        static unsigned char color[3];
        float t = j + i*0.001f;
        memcpy(color, &t, 3);
        fwrite(color, 1, 3, fp);

    // 其实更简单粗爆的方式是
         //fwrite(&t, 1, 3, fp);
    }

          代码运行后会生成一种PPM格式的图像,如下图所示:

          图像多少有点分形的感觉。PPM格式的图像不太常见,它是一种非常简单的图像格式。在我写的软件Why数学图像生成工具中可以查看,当然我也将该图像的生成算法写到这个软件中,相关代码如下:

    #ifndef _PixelFloatConvertInt_H_
    #define _PixelFloatConvertInt_H_
    
    // --------------------------------------------------------------------------------------
    
    #include "IPixelEquation.h"
    
    // --------------------------------------------------------------------------------------
    
    class CPixelFloatConvertInt : public IPixelEquation
    {
    public:
        CPixelFloatConvertInt()
        {
            m_width = 1000;
            m_height = 1000;
        }
    
        const char*     GetName() const
        {
            return "Float Convert Int";
        }
    
        unsigned int    CalculatePixel(unsigned int x, unsigned int y)
        {
            float t = y + x*0.001f;
            unsigned int rst = *(unsigned int*)&t;
            rst |= 0xff000000;
            return rst;
        }
    };
    
    // --------------------------------------------------------------------------------------
    
    #endif

    使用Why数学图像生成工具可以查看该图像的红绿蓝三个分量:

    R通道图:

    G通道图:

    B通道图:

    代码稍做修改,分形效果更为明显:

        unsigned int    CalculatePixel(unsigned int x, unsigned int y)
        {
            float t = y/4+ x*0.001f;
            unsigned int rst = *(unsigned int*)&t;
            rst |= 0xff000000;
            return rst;
        }

  • 相关阅读:
    Project 01 PlantAndZomb
    iOS平台内存使用原则
    IOS之UIKit_Day22--23
    IOS之UIKit_Day21
    IOS之UIKit_Day20
    浅谈javascript数据类型,对象,类
    从输入一个url到加载页面发生了什么?
    d3.js(2)-svg
    d3.js(1)
    console.time和performance.now()
  • 原文地址:https://www.cnblogs.com/WhyEngine/p/4051001.html
Copyright © 2011-2022 走看看