首先新建一个c++空项目,然后添加tgaimage.htgaimage.cpp文件,源代码如下:

tgaimage.h

#ifndef __IMAGE_H__
#define __IMAGE_H__#include <fstream>#pragma pack(push,1)
struct TGA_Header {char idlength;char colormaptype;char datatypecode;short colormaporigin;short colormaplength;char colormapdepth;short x_origin;short y_origin;short width;short height;char  bitsperpixel;char  imagedescriptor;
};
#pragma pack(pop)struct TGAColor {unsigned char bgra[4];unsigned char bytespp;TGAColor() : bgra(), bytespp(1) {for (int i = 0; i < 4; i++) bgra[i] = 0;}TGAColor(unsigned char R, unsigned char G, unsigned char B, unsigned char A = 255) : bgra(), bytespp(4) {bgra[0] = B;bgra[1] = G;bgra[2] = R;bgra[3] = A;}TGAColor(unsigned char v) : bgra(), bytespp(1) {for (int i = 0; i < 4; i++) bgra[i] = 0;bgra[0] = v;}TGAColor(const unsigned char *p, unsigned char bpp) : bgra(), bytespp(bpp) {for (int i = 0; i < (int)bpp; i++) {bgra[i] = p[i];}for (int i = bpp; i < 4; i++) {bgra[i] = 0;}}unsigned char& operator[](const int i) { return bgra[i]; }TGAColor operator *(float intensity) const {TGAColor res = *this;intensity = (intensity > 1.f ? 1.f : (intensity < 0.f ? 0.f : intensity));for (int i = 0; i < 4; i++) res.bgra[i] = bgra[i] * intensity;return res;}
};class TGAImage {
protected:unsigned char* data;int width;int height;int bytespp;bool   load_rle_data(std::ifstream &in);bool unload_rle_data(std::ofstream &out);
public:enum Format {GRAYSCALE = 1, RGB = 3, RGBA = 4};TGAImage();TGAImage(int w, int h, int bpp);TGAImage(const TGAImage &img);bool read_tga_file(const char *filename);bool write_tga_file(const char *filename, bool rle = true);bool flip_horizontally();bool flip_vertically();bool scale(int w, int h);TGAColor get(int x, int y);bool set(int x, int y, TGAColor &c);bool set(int x, int y, const TGAColor &c);~TGAImage();TGAImage & operator =(const TGAImage &img);int get_width();int get_height();int get_bytespp();unsigned char *buffer();void clear();
};#endif //__IMAGE_H__

tgaimage.cpp

#include <iostream>
#include <fstream>
#include <string.h>
#include <time.h>
#include <math.h>
#include "tgaimage.h"TGAImage::TGAImage() : data(NULL), width(0), height(0), bytespp(0) {}TGAImage::TGAImage(int w, int h, int bpp) : data(NULL), width(w), height(h), bytespp(bpp) {unsigned long nbytes = width * height*bytespp;data = new unsigned char[nbytes];memset(data, 0, nbytes);
}TGAImage::TGAImage(const TGAImage &img) : data(NULL), width(img.width), height(img.height), bytespp(img.bytespp) {unsigned long nbytes = width * height*bytespp;data = new unsigned char[nbytes];memcpy(data, img.data, nbytes);
}TGAImage::~TGAImage() {if (data) delete[] data;
}TGAImage & TGAImage::operator =(const TGAImage &img) {if (this != &img) {if (data) delete[] data;width = img.width;height = img.height;bytespp = img.bytespp;unsigned long nbytes = width * height*bytespp;data = new unsigned char[nbytes];memcpy(data, img.data, nbytes);}return *this;
}bool TGAImage::read_tga_file(const char *filename) {if (data) delete[] data;data = NULL;std::ifstream in;in.open(filename, std::ios::binary);if (!in.is_open()) {std::cerr << "can't open file " << filename << "\n";in.close();return false;}TGA_Header header;in.read((char *)&header, sizeof(header));if (!in.good()) {in.close();std::cerr << "an error occured while reading the header\n";return false;}width = header.width;height = header.height;bytespp = header.bitsperpixel >> 3;if (width <= 0 || height <= 0 || (bytespp != GRAYSCALE && bytespp != RGB && bytespp != RGBA)) {in.close();std::cerr << "bad bpp (or width/height) value\n";return false;}unsigned long nbytes = bytespp * width*height;data = new unsigned char[nbytes];if (3 == header.datatypecode || 2 == header.datatypecode) {in.read((char *)data, nbytes);if (!in.good()) {in.close();std::cerr << "an error occured while reading the data\n";return false;}}else if (10 == header.datatypecode || 11 == header.datatypecode) {if (!load_rle_data(in)) {in.close();std::cerr << "an error occured while reading the data\n";return false;}}else {in.close();std::cerr << "unknown file format " << (int)header.datatypecode << "\n";return false;}if (!(header.imagedescriptor & 0x20)) {flip_vertically();}if (header.imagedescriptor & 0x10) {flip_horizontally();}std::cerr << width << "x" << height << "/" << bytespp * 8 << "\n";in.close();return true;
}bool TGAImage::load_rle_data(std::ifstream &in) {unsigned long pixelcount = width * height;unsigned long currentpixel = 0;unsigned long currentbyte = 0;TGAColor colorbuffer;do {unsigned char chunkheader = 0;chunkheader = in.get();if (!in.good()) {std::cerr << "an error occured while reading the data\n";return false;}if (chunkheader < 128) {chunkheader++;for (int i = 0; i < chunkheader; i++) {in.read((char *)colorbuffer.bgra, bytespp);if (!in.good()) {std::cerr << "an error occured while reading the header\n";return false;}for (int t = 0; t < bytespp; t++)data[currentbyte++] = colorbuffer.bgra[t];currentpixel++;if (currentpixel > pixelcount) {std::cerr << "Too many pixels read\n";return false;}}}else {chunkheader -= 127;in.read((char *)colorbuffer.bgra, bytespp);if (!in.good()) {std::cerr << "an error occured while reading the header\n";return false;}for (int i = 0; i < chunkheader; i++) {for (int t = 0; t < bytespp; t++)data[currentbyte++] = colorbuffer.bgra[t];currentpixel++;if (currentpixel > pixelcount) {std::cerr << "Too many pixels read\n";return false;}}}} while (currentpixel < pixelcount);return true;
}bool TGAImage::write_tga_file(const char *filename, bool rle) {unsigned char developer_area_ref[4] = { 0, 0, 0, 0 };unsigned char extension_area_ref[4] = { 0, 0, 0, 0 };unsigned char footer[18] = { 'T','R','U','E','V','I','S','I','O','N','-','X','F','I','L','E','.','\0' };std::ofstream out;out.open(filename, std::ios::binary);if (!out.is_open()) {std::cerr << "can't open file " << filename << "\n";out.close();return false;}TGA_Header header;memset((void *)&header, 0, sizeof(header));header.bitsperpixel = bytespp << 3;header.width = width;header.height = height;header.datatypecode = (bytespp == GRAYSCALE ? (rle ? 11 : 3) : (rle ? 10 : 2));header.imagedescriptor = 0x20; // top-left originout.write((char *)&header, sizeof(header));if (!out.good()) {out.close();std::cerr << "can't dump the tga file\n";return false;}if (!rle) {out.write((char *)data, width*height*bytespp);if (!out.good()) {std::cerr << "can't unload raw data\n";out.close();return false;}}else {if (!unload_rle_data(out)) {out.close();std::cerr << "can't unload rle data\n";return false;}}out.write((char *)developer_area_ref, sizeof(developer_area_ref));if (!out.good()) {std::cerr << "can't dump the tga file\n";out.close();return false;}out.write((char *)extension_area_ref, sizeof(extension_area_ref));if (!out.good()) {std::cerr << "can't dump the tga file\n";out.close();return false;}out.write((char *)footer, sizeof(footer));if (!out.good()) {std::cerr << "can't dump the tga file\n";out.close();return false;}out.close();return true;
}// TODO: it is not necessary to break a raw chunk for two equal pixels (for the matter of the resulting size)
bool TGAImage::unload_rle_data(std::ofstream &out) {const unsigned char max_chunk_length = 128;unsigned long npixels = width * height;unsigned long curpix = 0;while (curpix < npixels) {unsigned long chunkstart = curpix * bytespp;unsigned long curbyte = curpix * bytespp;unsigned char run_length = 1;bool raw = true;while (curpix + run_length < npixels && run_length < max_chunk_length) {bool succ_eq = true;for (int t = 0; succ_eq && t < bytespp; t++) {succ_eq = (data[curbyte + t] == data[curbyte + t + bytespp]);}curbyte += bytespp;if (1 == run_length) {raw = !succ_eq;}if (raw && succ_eq) {run_length--;break;}if (!raw && !succ_eq) {break;}run_length++;}curpix += run_length;out.put(raw ? run_length - 1 : run_length + 127);if (!out.good()) {std::cerr << "can't dump the tga file\n";return false;}out.write((char *)(data + chunkstart), (raw ? run_length * bytespp : bytespp));if (!out.good()) {std::cerr << "can't dump the tga file\n";return false;}}return true;
}TGAColor TGAImage::get(int x, int y) {if (!data || x < 0 || y < 0 || x >= width || y >= height) {return TGAColor();}return TGAColor(data + (x + y * width)*bytespp, bytespp);
}bool TGAImage::set(int x, int y, TGAColor &c) {if (!data || x < 0 || y < 0 || x >= width || y >= height) {return false;}memcpy(data + (x + y * width)*bytespp, c.bgra, bytespp);return true;
}bool TGAImage::set(int x, int y, const TGAColor &c) {if (!data || x < 0 || y < 0 || x >= width || y >= height) {return false;}memcpy(data + (x + y * width)*bytespp, c.bgra, bytespp);return true;
}int TGAImage::get_bytespp() {return bytespp;
}int TGAImage::get_width() {return width;
}int TGAImage::get_height() {return height;
}bool TGAImage::flip_horizontally() {if (!data) return false;int half = width >> 1;for (int i = 0; i < half; i++) {for (int j = 0; j < height; j++) {TGAColor c1 = get(i, j);TGAColor c2 = get(width - 1 - i, j);set(i, j, c2);set(width - 1 - i, j, c1);}}return true;
}bool TGAImage::flip_vertically() {if (!data) return false;unsigned long bytes_per_line = width * bytespp;unsigned char *line = new unsigned char[bytes_per_line];int half = height >> 1;for (int j = 0; j < half; j++) {unsigned long l1 = j * bytes_per_line;unsigned long l2 = (height - 1 - j)*bytes_per_line;memmove((void *)line, (void *)(data + l1), bytes_per_line);memmove((void *)(data + l1), (void *)(data + l2), bytes_per_line);memmove((void *)(data + l2), (void *)line, bytes_per_line);}delete[] line;return true;
}unsigned char *TGAImage::buffer() {return data;
}void TGAImage::clear() {memset((void *)data, 0, width*height*bytespp);
}bool TGAImage::scale(int w, int h) {if (w <= 0 || h <= 0 || !data) return false;unsigned char *tdata = new unsigned char[w*h*bytespp];int nscanline = 0;int oscanline = 0;int erry = 0;unsigned long nlinebytes = w * bytespp;unsigned long olinebytes = width * bytespp;for (int j = 0; j < height; j++) {int errx = width - w;int nx = -bytespp;int ox = -bytespp;for (int i = 0; i < width; i++) {ox += bytespp;errx += w;while (errx >= (int)width) {errx -= width;nx += bytespp;memcpy(tdata + nscanline + nx, data + oscanline + ox, bytespp);}}erry += h;oscanline += olinebytes;while (erry >= (int)height) {if (erry >= (int)height << 1) // it means we jump over a scanlinememcpy(tdata + nscanline + nlinebytes, tdata + nscanline, nlinebytes);erry -= height;nscanline += nlinebytes;}}delete[] data;data = tdata;width = w;height = h;return true;
}

然后添加一个main.cpp文件,代码如下:

#include "tgaimage.h"const TGAColor white = TGAColor(255, 255, 255, 255);
const TGAColor red = TGAColor(255, 0, 0, 255);
int main(int argc, char** argv) {TGAImage image(100, 100, TGAImage::RGB);image.set(52, 41, red);image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_tga_file("output.tga"); return 0;
}

可以发现在自己的项目文件夹下生成了一个output.tga文件。

ps或者其他软件打开就可以看见一个像素点了。

参考资料:https://github.com/ssloy/tinyrenderer/wiki/Lesson-0-getting-started

通过c++画一个像素点相关推荐

  1. 用计算机图形画一个杯子,计算机图形学期末考试试卷(D卷)

    计算机图形学期末考试试卷(D 卷) 一. 填空题(每空1分,共10分) 1. 图形的表示方法有两种: 点阵法 和 参数法 . 2. 目前常用的两个事实图形软件标准是OpenGL 和 DirectX . ...

  2. Python编程 利用Python画一个爱心

    作者简介:一名在校计算机学生.每天分享Python的学习经验.和学习笔记.   座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​​ 目录 前言 一.所使用的库 1.turtle库 2.情人 ...

  3. Directx11教程(6) 画一个简单的三角形(2)

    在上篇教程中,我们实现了在D3D11中画一个简单的三角形,但是,当我们改变窗口大小时候,三角形形状却随着窗口高宽比例改变而改变,如下图所示: 这是因为我们改变了窗口大小,但后缓冲大小在程序初始化时候, ...

  4. 用Python Turtle库画一个萌化的蜘蛛侠

    你是从什么时候开始喜欢上漫威电影的?美国队长,钢铁侠,雷神? 我先入坑的是因为看了蜘蛛侠,小时候看完就幻想着什么时候自己也能成为一个英雄,我觉得第一代蜘蛛侠刻画得是最好的,也是给我印象最深刻的一代蜘蛛 ...

  5. 使用AI画一个冠状病毒

    前言 近期有关于冠状病毒的信息很多,相关学术论文数目也在不断增加.为了让论文好看一点,今天我们来使用AI画一个冠状病毒,练习练习AI的画图技巧. 软件 Adobe Illustrator CC 201 ...

  6. 用ggplot包画一个简单饼图

    用ggplot包画一个简单饼图 首先用library函数加载ggplot2包 1 2 3 4 library(ggplot2) library(dplyr) library(tidyr) librar ...

  7. 用python画哆啦a梦的身体_用Python画一个哆啦A梦

    Python自带的turtle海龟绘图库功能十分强大,使用起来也很简单方便,今天我们就使用海龟绘图画一个我们都很喜欢的卡通形象-哆啦A梦头像.我们将整个头像分为几个部分分别定义相关的绘制函数,下面分别 ...

  8. 如何用 css 画一个心形

    如何用 css 画一个心形 (How to draw hearts using CSS) 用两个长方形切圆角倾斜位移并合并为一个心形 第一步 画一个长方形 (Draw a rectangle) 这个长 ...

  9. matlab 画一个矩形

    画一个矩形 %rectangle('Position',[x,y,w,h],'PropertyName',propertyvalue) %axis([xmin,xmax,ymin,ymax]) clc ...

最新文章

  1. S6 edge+的多米诺骨牌效应:大屏的趋势
  2. Office Tab免费版:标签化浏览和编辑Office文档
  3. Couldn‘t find grammar element for class javax.ws.rs.core.Response(没有解决)
  4. UOJ59 WC2013 小Q运动季
  5. python免杀技术---shellcode的加载与执行
  6. screen命令使用说明
  7. html页面嵌入markdown,html – 在R markdown中嵌入图形输出
  8. 模型可视化工具netron
  9. android网易云桌面歌词,网易云怎么设置桌面歌词?
  10. unity3d游戏开发第2版 pdf_从零开始学基于ARKit的Unity3d游戏开发系列1
  11. UnityShader实现漫反射光照模型和高光反射光照模型
  12. #最短路径,最小生成树#CH 6202 黑暗城堡
  13. DELPHI读取网页源文件和获取字符串
  14. 研究生图像处理该怎的自学_我的研究生这三年
  15. 零基础深入浅出主成分分析PCA
  16. 我看凯立德GPS软件的规划问题
  17. Excel 重复格式检验高亮为空不展示,15位不生效问题,手机号格式
  18. 拨乱反正:“通过RAMDirectory缓写提高性能”是错误的!
  19. 利用静态实现单例模式
  20. 合泰杯——合泰单片机工程5之串口通信

热门文章

  1. 客运综合管理—票据入库
  2. N76E003,C51开发不编译
  3. 开机cmd窗口自动打开dinoklafbzor的解决方法
  4. 计算机信息管理专业好毕业吗,我是计算机信息管理专业毕业的,在学校的时候老师说我们毕业之后是从事管理工作的...
  5. Fundation中常用结构体
  6. IOS开发学习---Fundation框架和UIKit框架
  7. 贡献黑莓SDK for Eclipse 工具
  8. java调用帆软cpt文件_报表开发导出各种格式文件的API
  9. python2和python3同时安装无法使用pip2解决方法
  10. css3宽度变大动画_动画演示14种流量计的工作原理,真涨见识