分形/計算機圖形技術/2D/gfile
"Any computer-generated picture is a finite collection of pixels." ( A Dudko, M Yampolsky)[1]
a matrix of color entries (a.k.a. image)
圖形檔案
可以
- 直接建立圖形檔案
- 開啟現有的圖形檔案
- 新增/讀取/刪除圖形檔案的文字資訊
圖形檔案型別
- 影像
- 靜態影像
- SDR 檔案格式:PNG8、JPG、
- HDR 檔案格式:FITS、JPEG XR、JPEG XT、Logluv TIFF、exr (OpenEXR)、RGBE 影像格式、TIFF、PNG64、AV1
- 動態影像
- 影片(ogg 檔案) - 需要特殊的程式(檢視器)才能執行
- 動畫(沒有檢視器的動畫 GIF 檔案)
- 靜態影像
- 非影像檔案
數字影像表示
- 光柵
- 向量
影像的動態範圍
- LDR
- 標準 LDR
- 從 HDR 對映的 LDR 色調
- 偽 HDR 或曝光混合或曝光融合 = 從多個曝光中合併的影像,而無需建立中間 HDR 影像,也無需使用色調對映
- HDR
- 資料 = 未處理的 HDR = 浮點幀緩衝區(在 OpenGl GL_RGB16F、GL_RGBA16F、GL_RGB32F 或 GL_RGBA32F 中)
- AV1 影像檔案格式 (AVIF) 是一種開放的、免版稅的影像檔案格式規範,用於儲存使用 AV1 壓縮的影像或影像序列,採用 HEIF 容器格式。[
- 維基百科中的圖形檔案格式比較
- Commons 中的檔案型別
- 美國國家醫學圖書館的圖形格式指南
- 美國國家醫學圖書館的檔案格式
- 分形論壇允許的檔案型別:kfr、jpg、jpeg、gif、png、ufr、upr、uxf、ucl、ufm、map、par、m3a、m3f、m3i、m3p、m3c、frag、m3v、zip、ifp、lua、txt
| 格式 | 支援的位深 | 在動畫和 VFX 中的使用 |
|---|---|---|
| JPEG | 8 位 sRGB | 預覽渲染。使用 100% 的質量。檔案尺寸小,在播放器中載入速度快。也可以用作 3D 中的背景或動作匹配的底片。永遠不要用作中間格式 TARGA (tga) |
| TARGA (tga) | 8 位 sRGB | 非常古老,但仍然用作電視廣告後期製作中的中間格式 |
| TIFF | 8 位和 16 位 sRGB。32 位線性浮點。 | 如果需要中間 16 位整數,則為標準格式 |
| PNG | 8 位和 16 位 sRGB。8 位調色盤。 | 標準 Web 格式。支援無失真壓縮,因此非常有用 |
| Cineon (dpx, cin) | 8、10、12、16 sRGB 和對數 | 用作交付、中間和輸出格式。電影轉電視和數字中間調色的標準格式 |
| Photoshop (psd) | 8 位和 16 位 sRGB。32 位線性浮點 | Photoshop 工作的預設格式。可以用作中間格式,將圖層交付到下一階段 |
| Radiance (hdr) | 32 位線性浮點 | 儲存用於基於影像的照明的 HDR 影像的標準格式 |
| OpenEXR (exr) | 16 位線性浮點。32 位線性浮點 | VFX 渲染和中間格式的標準 |
| pfm | 四位元組 IEEE 754 單精度浮點擴充套件 | PFM 受 Photoshop[16]、GIMP 和 ImageMagick 的支援。它受事實上的參考實現 netpbm 的支援 |

AV1 影像檔案格式 (AVIF) 是一種開放的、免版稅的影像檔案格式規範,用於儲存使用 AV1 壓縮的影像或影像序列,採用 HEIF 容器格式。[3] 它與 HEIC 競爭,HEIC 使用相同的基於 ISOBMFF 的容器格式,但使用 HEVC 進行壓縮。AVIF 規範的 1.0.0 版於 2019 年 2 月定稿。
在 Netflix 於 2020 年進行的一系列測試中,AVIF 表現出比 JPEG 更好的壓縮效率,以及更好的細節保留、更少的塊狀偽影,以及在自然影像、文字和圖形的合成影像中更少的顏色溢位。[4]
AVIF 特性
- 多個顏色空間,包括
- HDR(使用 PQ(傳遞函式)[5]Template:Failed verification 或混合對數伽馬 (HLG) 傳遞函式,以及 BT.2020 色彩原色,作為 BT.2100 的一部分)[3]
- 標準動態範圍 (SDR),使用 sRGB / BT.709 / BT.601 或寬色域
- 透過編碼無關程式碼點 (CICP)(ITU-T H.273 和 ISO/IEC 23091-2)或 ICC 配置檔案[6] 傳輸顏色空間訊號
- 無失真壓縮和有失真壓縮
- 8 位、10 位和 12 位色深[6]
- 單色(alpha/深度)或多元件
- 4:2:0、4:2:2、4:4:4 色度取樣和 RGB
- 膠片顆粒[7]
- 影像序列/動畫
- AVIF 是由開放媒體聯盟開發的一種檔案格式。它是一個開放的標準,在主要網頁瀏覽器中已經得到了相當廣泛的支援,用於標準影像。AVIF 比 JPG 具有眾多優勢
- PNG 支援 1、2、4、8 和 16 位灰度以及 8 和 16 位每樣本(即 24 和 48 位)真彩色。
- PFM 檔案 - 用於 HDR 影像的浮點影像格式
- EXR(OpenEXR):16 位 OpenEXR 檔案可以被認為是通用情況下色彩精度/檔案大小折衷的良好選擇[8] OpenEXR 支援使用以下顏色深度:16 位浮點(半精度)、32 位浮點和 32 位無符號整數
- TIFF
- RGBE 影像格式或 Radiance HDR 是 Gregory Ward Larson 為 Radiance 渲染系統發明的一種影像格式。它將畫素儲存為 RGB(紅、綠、藍)值的每個位元組,並使用一個位元組的共享指數。因此,它每個畫素儲存四個位元組。
- Gertbuschmann 的描述
- 獨立 JPEG 組
- JPEGclub.org 開發新的 JPEG 功能並維護獨立 JPEG 組 (IJG) 的軟體。
- jpeg-faq
- compression-faq
- 參考
- IJG 軟體的三大工具
- cjpeg (壓縮 JPEG):壓縮命名影像檔案,如果未命名檔案則壓縮標準輸入,並在標準輸出上生成 JPEG/JFIF 檔案。當前支援的輸入檔案格式為:PPM(PBMPLUS 彩色格式)、PGM(PBMPLUS 灰度格式)、BMP、Targa 和 RLE(Utah Raster Toolkit 格式)。(僅當 URT 庫可用時才支援 RLE。)另請參閱 新 cjpeg 功能
- djpeg(解壓縮 JPEG)
- jpegtran(轉碼 JPEG - 無損)
Command 'cjpeg' not found, but can be installed with: sudo apt install libjpeg-progs # version 1:9d-1, or sudo apt install libjpeg-turbo-progs # version 2.1.2-0ubuntu1
如何使用它
./a.out | cjpeg > temp.jpg && open temp.jpg
- Richard Zanibbi 於 1998 年 5 月編寫的 cprogram_to_read_PGM/PGM.c
- John Burkardt 編寫的 PGMB_IO 二進位制可移植灰度圖 (PGM) 檔案讀寫實用程式
- John Burkardt 提供的二進位制 pgm 檔案示例
// create 1D array
iSize = iWidth*iHeight; // size = number of points in array
/* create dynamic 1D arrays for colors ( shades of gray ) */
data = malloc( iSize * sizeof(unsigned char) );
if (data == NULL )
{
fprintf(stderr," Could not allocate memory\n");
return 1;
}
// *******************************************************************************************
// ********************************** save A array to pgm file ****************************
// *********************************************************************************************
int
SaveArray2PGMFile (unsigned char A[], int a, int b, int c, char *comment)
{
FILE *fp;
const unsigned int MaxColorComponentValue = 255; /* color component is coded from 0 to 255 ; it is 8 bit color file */
char name[100]; /* name of file */
snprintf (name, sizeof name, "%d_%d_%d", a, b, c ); /* */
char *filename = strcat (name, ".pgm");
char long_comment[200];
sprintf (long_comment, "fc(z)=z*(1+z)*(1+z)*(C-(2C+1)*z+(3+4*C)*z*z/4) %s", comment);
// save image array to the pgm file
fp = fopen (filename, "wb"); // create new file,give it a name and open it in binary mode
fprintf (fp, "P5\n # %s\n %u %u\n %u\n", long_comment, iWidth, iHeight, MaxColorComponentValue); // write header to the file
size_t rSize = fwrite (A, sizeof(A[0]), iSize, fp); // write whole array with image data bytes to the file in one step
fclose (fp);
// info
if ( rSize == iSize)
{
printf ("File %s saved ", filename);
if (long_comment == NULL || strlen (long_comment) == 0)
printf ("\n");
else { printf (". Comment = %s \n", long_comment); }
}
else {printf("wrote %zu elements out of %llu requested\n", rSize, iSize);}
return 0;
}
// free memory
free(data);
- 以下是用於建立 pbm 檔案的各種程式[9]
- Mukund 編寫的 C 語言中的 PPM 檔案
- JOSEPH THOMAS 編寫的 C 語言中的 ppm 檔案
- Ilya Voyager 編寫的 PGM 檔案和 C++ 程式
- Lori L Scarlatos 使用 glut 載入和繪製 ppm/pgm 檔案
- John Meacham 編寫的 C 語言下黑手:洩漏的編輯
- 來自墨爾本大學的 Haskell 中的 ppm 檔案
- Ryan Lothian 編寫的 Haskell 中的 PPM
- Daniel Díaz 編寫的使用 PPM 的 Haskell 中的影像處理
P3 #the P3 means colors are in ascii, then 3 columns and 2 rows, then 255 for max color, then RGB triplets 3 2 255 255 0 0 0 255 0 0 0 255 255 255 0 255 255 255 0 0 0
影像(展開):w:Image:tiny6pixel.png
上面的影像使用 imagemagick 命令沒有插值地展開。
convert -sample %6400 tiny6pixel.ppm tiny6pixel.png
相同影像的 P6 格式將以一個位元組(因此每個畫素三個位元組)的順序儲存每個畫素的每個顏色分量,順序為紅色、綠色然後藍色。檔案將更小,但顏色資訊對人類來說將不可讀。
P6
#any comment string
3 2
255
!@#$%^&*()_+|{}:"<
PPM 格式未壓縮,因此與壓縮格式相比需要更多空間和頻寬。例如,上面的 192x128 PNG 影像的檔案大小為 187 位元組。轉換為 192x128 PPM 影像後,檔案大小為 73848 位元組。PPM 格式通常是用於影像處理的中間格式,然後轉換為更有效的格式,例如 PNG (可移植網路圖形) 格式。PPM 格式可以轉換為 PNG,不會丟失資訊。
PPM 格式當然很容易從頭開始編寫。以下 Python 程式碼生成了上面的示例影像。它可以透過讀取或構建數值資料陣列,並編寫將資料轉換為顏色三元組的轉換來適應生成有用的影像。
#!/usr/bin/python
triplets=[ [255, 0, 0], [0, 255, 0], [0, 0, 255], [255, 255, 0], [255, 255, 255], [0, 0, 0] ]
width=3; height=2
comment='any comment string'
ftype='P6' #use 'P3' for ascii, 'P6' for binary
ppmfile=open('testimage.ppm','wb')
ppmfile.write("%s\n" % (ftype))
ppmfile.write("#%s\n" % comment )
ppmfile.write("%d %d\n" % (width, height))
ppmfile.write("255\n")
if ftype=='P3':
for red,green,blue in triplets:
ppmfile.write("%d %d %d\n" % (red,green,blue))
elif ftype=='P6': #print 1 byte per color
for red,green,blue in triplets:
ppmfile.write("%c%c%c" % (red,green,blue))
ppmfile.close()
類似的 C 程式碼
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define xor(a, b) (((!a && b)) || (a && !b))
int main (int argc, char * argv[]){
/* Declare the variables */
FILE* ppmFile;
int columns, rows, numberOfPixelsInPicture;
/* Check the input arguments */
if(argc != 4){
printf("Usage: %s cols rows fname.ppm\n\n", *argv);
return 1;
}
/* Open the file and write the first 4 lines to it */
ppmFile = fopen(argv[3], "w");
columns = atoi(argv[1]);
rows = atoi(argv[2]);
numberOfPixelsInPicture = rows * columns;
fprintf(ppmFile, "P3\n%d\n%d\n255\n", columns, rows);
int m, n;
for(m=0;m<rows;m++) {
for(n=0;n<columns;n++) {
/* Set the pixels in the bottom left of the picture a green-yellow color */
if(m>n) {
fprintf(ppmFile, "%d 255 %d\n", (256*m)/rows, (256*n)/columns);
} else if(xor((m/10)%2,(n/10)%2)) {
/* Create a checkerboard pattern in the upper-right of the picture */
/* Create the blue-red pixels in the checkerboard pattern */
fprintf(ppmFile, "%d 0 %d\n", (255*m*n)/numberOfPixelsInPicture, 255 -(255*m*n)/numberOfPixelsInPicture);
} else {
/* Create the black pixels in the checkerboard pattern */
fprintf(ppmFile, "0 0 0\n");
}
}
/* Print a blank line between rows */
fprintf(ppmFile, "\n");
}
fclose(ppmFile);
return 0;
}
彙編程式碼
; create a ppmb file by ker2x
; http://www.fractalforums.com/programming/an-absolute-beginner-to-x64-asm-on-linux/
: yasm -f elf64 ppmb.asm
; gcc -o ppmb ppmb.o
; ./ppmb | hexdump
segment .data
header: db 'P6 4 4 255', 0x0a
headerlen: equ $-header
image: db 255,0,0, 0,255,0, 0,0,255, 255,255,255
imagelen: equ $-image
segment .text
global main
main:
mov eax, 4
mov ebx, 1
mov ecx, header
mov edx, headerlen
int 0x80
mov eax, 4
mov ebx, 1
mov ecx, image
mov edx, imagelen
int 0x80
mov eax, 4
int 0x80
mov eax, 4
int 0x80
mov eax, 4
int 0x80
; Call sys_exit(0)
mov eax, 1
xor ebx, ebx
int 0x80
C 程式碼
一種顏色的靜態陣列 : 在 C 中用於建立 pgm 文字檔案的程式碼
#include <stdio.h>
int main(){
int iX,iY;
const int iXmax = 300;
const int iYmax = 300;
/* color is coded from 0 to 255 */
/* it is 8 bit color RGB file */
const int MaxColorComponentValue=255;
FILE * fp;
char *filename="m.pgm";
char *comment="# this is my new text pgm file "; /* comment should start with # */
static unsigned char color;
/*create new file,give it a name and open it in text mode */
fp= fopen(filename,"w"); /* text mode */
/*write ASCII header to the file*/
fprintf(fp,"P2\n%s\n%d %d\n%d\n",comment,iXmax,iYmax,MaxColorComponentValue);
/*write image data bytes to the file*/
for(iY=0;iY<iYmax;++iY){
for(iX=0;iX<iXmax;++iX){
color=150; /* compute pixel color (8 bit = 1 byte) */
fprintf(fp," %d ", color); /*write color to the file*/
}
fprintf(fp," \n ");
}
fclose(fp);
printf("OK\n");
getchar();
return 0;
}
編譯它
gcc m.c
執行它
./a.out
記住
- fwrite 用於二進位制檔案
- fprintf 用於二進位制檔案和文字檔案
因此,如果您想使用 fwrite,那麼您將獲得二進位制檔案(即使您以文字模式開啟它)。
C 程式碼 : 用於整個影像的靜態二維陣列
#include <stdio.h>
int main(){
int iX,iY;
const int iXmax = 100;
const int iYmax = 100;
unsigned char data[iYmax][iXmax]; /* 2D array for colors ( shades of gray ) */
const int MaxColorComponentValue=255; /* color component is coded from 0 to 255 ; it is 8 bit color file */
FILE * fp;
char *filename="n.pgm";
char *comment="# this is my new binary pgm file";/* comment should start with # */
/* fill the data array */
for(iY=0;iY<iYmax;++iY){
for(iX=0;iX<iXmax;++iX){
data[iY][iX]=255;
}
}
}
/* write the whole data array to ppm file in one step */
fp= fopen(filename,"wb"); /*create new file,give it a name and open it in binary mode */
fprintf(fp,"P5\n %s\n %d %d\n %d\n",comment,iXmax,iYmax,MaxColorComponentValue); /*write header to the file*/
fwrite(data,sizeof data,1,fp); /*write image data bytes to the file*/
fclose(fp);
printf("OK - file %s saved\n", filename);
return 0;
}
C 程式碼 : 虛擬二維陣列和動態一維陣列
這裡的影像是虛擬二維陣列,但在程式中我們使用一維陣列。
索引之間的關係
i = ix + iy*iWidth; // index of 1D array ix = i % iWidth; iy = (i- ix) / iWidth;
這是整個程式,我們只檢查陣列索引的範圍,而沒有使用顯式陣列
#include <stdio.h>
/* --------- global variables ----------------- */
// 2D array
// Indexes of array starts from 0 not 1
unsigned int ix, iy;
unsigned int ixMin = 0;
unsigned int ixMax = 3; //
unsigned int iWidth ; // = (ixMax -ixMin + 1) = 4
unsigned int iyMin = 0;
unsigned int iyMax = 3; //
unsigned int iHeight ; //= (iyMax -iyMin + 1) = 4
// The size of array has to be a positive constant integer
unsigned int i2Dsize ; // = iWidth*iHeight = 16
// 1D array
unsigned int i; // index of 1D array
unsigned int iMin = 0;
// Indexes of array starts from 0 not 1 so the highest elements of an array is = array_name[size-1].
unsigned int iMax ; // = i2Dsize-1; // = 15
// The size of array has to be a positive constant integer
unsigned int i1Dsize ; // = i2Dsize = (iMax -iMin + 1) = 16 ; 1D array with the same size as 2D array
/* ---------- functions ----------------*/
/* gives position of 2D point (iX,iY) in 1D array ; uses also global variable iWidth */
unsigned int f(unsigned int ix, unsigned int iy)
{ return ix + iy*iWidth; }
/* ---------------------- main ------------------*/
int main()
{
iWidth = (ixMax -ixMin + 1); //
iHeight = (iyMax -iyMin + 1); //
i2Dsize = iWidth*iHeight; // number of points in array
iMax = i2Dsize-1; // Indexes of array starts from 0 not 1 so the highest elements of an array is = array_name[size-1].
i1Dsize = i2Dsize; // 1D array with the same size as 2D array
// first method using 1D index i
for (i=iMin; i<i1Dsize; ++i) printf(" %d \n", i ); // from 0 to 15
// second method using 1D index i
for (i=iMin; i<=iMax ; ++i) printf(" %d \n", i ); // from 0 to 15
// check second method using 1D index i
for (i=iMin; i<=iMax ; ++i) // i from 0 to 15
{ ix = i % iWidth;
iy = ( i- ix) / iWidth; // inversion of f function
printf(" ix = %d ; iy = %d ; i = %d \n",ix , iy , i );}
// using 2D indexes : iy and ix
for(iy=iyMin;iy<=iyMax;++iy)
for(ix=ixMin;ix<=ixMax;++ix) printf(" ix = %d ; iy = %d ; i = %d \n", ix, iy, f(ix,iy) );
return 0;
}
用於二進位制 B@W PBM 檔案的 Lua 程式碼
-- The Computer Language Shootout
-- http://shootout.alioth.debian.org/
-- contributed by Mike Pall
local width = tonumber(arg and arg[1]) or 100
local height, wscale = width, 2/width
local m, limit2 = 50, 4.0
local write, char = io.write, string.char
write("P4\n", width, " ", height, "\n")
for y=0,height-1 do
local Ci = 2*y / height - 1
for xb=0,width-1,8 do
local bits = 0
local xbb = xb+7
for x=xb,xbb < width and xbb or width-1 do
bits = bits + bits
local Zr, Zi, Zrq, Ziq = 0.0, 0.0, 0.0, 0.0
local Cr = x * wscale - 1.5
for i=1,m do
local Zri = Zr*Zi
Zr = Zrq - Ziq + Cr
Zi = Zri + Zri + Ci
Zrq = Zr*Zr
Ziq = Zi*Zi
if Zrq + Ziq > limit2 then
bits = bits + 1
break
end
end
end
if xbb >= width then
for x=width,xbb do bits = bits + bits + 1 end
end
write(char(255-bits))
end
end
Python 程式碼
#!/usr/bin/python
# -*- coding: utf8 -*-
# code by User:Geek3
# https://commons.wikimedia.org/wiki/User:Geek3/ImageScripting
# use the PNM format (http://en.wikipedia.org/wiki/Netpbm_format)
# no need for external libraries
import colorsys
from math import *
width, height = 800, 600
# create header
image = open('pnm-example.ppm', 'w')
image.write('P3\n') # color image
image.write('{0} {1}\n'.format(width, height))
image.write('255\n')
def color(ix, iy):
'''return color for specific position'''
# create a rainbow ring
rx = (ix + 0.5 - width / 2.) / 100.
ry = (iy + 0.5 - height / 2.) / 100.
angle = pi + atan2(rx, ry)
amplitude = (rx**2 + ry**2) * exp(1 - (rx**2 + ry**2))
return colorsys.hsv_to_rgb(angle / (2*pi), amplitude, 1)
for iy in range(height):
for ix in range(width):
c = color(ix, iy)
image.write('{0} {1} {2}'.format(*[int(max(0, min(256*i, 255))) for i in c]))
if (ix < width - 1):
image.write(' ')
else:
image.write('\n')
image.close()
PFM(可移植浮點圖)是 HDR 影像的非官方浮點 Netpbm 影像格式[10]
- Antoine Toisoul Le Cann 編寫的 C++ 中的 PFM_ReadWrite 和 OpenCV 3 的版本
- wpfhtl 編寫的讀取和寫入 pfm 檔案,以及在 C++ 和 opencv 中檢視它
- Paul Debevec 編寫的 PFM 可移植浮點圖影像格式
- 來自 netpbm 的 pfm 格式描述
- C++ 中的 pfm 和 OpenCV
- c++
- imageMagic 檢查您是否具有 hdri 功能 : "identify -version" 並查詢 hdri[11]
- 顯示
- 建立
- gimp(2.8 不行,但 2.10 可以開啟)
- darktable
- c
可移植浮點圖 (PFM) 格式[12]
- 類似於 PPM / PGM / PBM
- 二進位制檔案
- 無壓縮
- 這些檔案中沒有註釋
結構
- 文字標題 = 3 行文字。三行文字中的每一行都以一個 1 位元組的 Unix 風格的回車符結尾:十六進位制中的 0x0a,而不是 Windows/DOS CR/LF 組合。
- 檔案以 type = ASCII 字元 "PF" 或 "Pf" 開頭。PF 表示它是彩色 PFM(3 通道 RGB 彩色影像)。Pf 表示它是灰度 PFM(單色單通道影像)。
- 下一行是解析度 : 2 個整數 = "[xres] [yres]" 表示影像的 x 和 y 解析度
- 最後一行包含單個浮點值:byte_order。
- 資料 : 每個畫素三個浮點數(每個畫素的一系列三個 4 位元組 IEEE 754 單精度浮點數,以從左到右、從下到上的順序指定)。
.pfm 檔案的文字標題採用以下格式
[type] [xres] [yres] [byte_order]
使用 xxd 檢查檔案
xxd memorial.pfm|head
輸出
00000000: 5046 0a35 3132 2037 3638 0a2d 312e 3030 PF.512 768.-1.00 00000010: 3030 3030 0a00 8020 3c00 001e 3b00 0038 0000... <...;..8
原始檔案格式:[13]
- 二進位制檔案[14],這意味著您不能在文字編輯器中開啟它,而只能在專用程式或十六進位制編輯器中開啟它
- 光柵檔案[15]:"由畫素(資料)值的順序列表組成,按行描述,從頂行開始,從左到右工作。" [16]
- 未壓縮
- 檔案不包含任何影像格式資訊,因此要使用原始檔案,應瞭解其結構和大小
- 檔案大小僅取決於影像尺寸和 畫素資料格式
型別
- 資料(非顏色資料,需要處理)
- 靜態影像(資料 = 顏色)
- 影片,如 Y4M
文件
來源
用於 RAW 編輯的庫:
- libraw
- libvips
- ImageMagic rgb raw
- rawtherapee
使用 raw 格式的示例 Fractal 程式:
- K I Martin 編寫的 SuperFractalThing(Java,跨平臺)
- Kalles Fraktaler 由 Karl Runmo 編寫,使用 kfb 地圖檔案
- kf-extras 用於處理 Kalles Fraktaler 2 輸出的程式
- 曼德爾機器 by Botond Kósa
- mandelbulber(m3p檔案僅包含引數,而.m3i檔案還包含原始影像)
用於原始檔案的圖片編輯器[18]
- RGBE影像格式或Radiance HDR 是Gregory Ward Larson為Radiance渲染系統發明的影像格式。 它將畫素儲存為 RGB(紅、綠、藍)值的每個位元組,以及一個共享的位元組指數。 因此,它每畫素儲存四個位元組。
- TIFF - 最高品質的柵格影像格式
- TIFF檔案中的通道也可以使用任何 IEEE 754 浮點格式,包括 128 位格式,用於 RGB、YCbCr 和 CIE Lab* 格式的每個畫素 384 位(48 位元組)和 CMYK 格式的每個畫素 512 位(64 位元組)。 同樣適用於任何 Alpha 通道[19]
- 支援無失真壓縮,在壓縮過程中不會丟失任何影像資料。 也可以使用未壓縮的 TIFF 影像。
- 支援 Alpha 通道(透明度)
- 它支援 YCbCr、RGB、CMYK 和 CIELab 色彩空間
- 並非所有網路服務或程式都支援它
- 開啟速度較慢,檔案較大
- libtiff - c 庫和實用程式
Dot 檔案 是描述 dot 語言中的圖表的文字檔案。 例如檔案
digraph "BinaryAddingMachine" {
a [shape=circle]
b [shape=circle]
a -> a [label="1/1",color=red];
a -> a [label="2/2",color=blue];
b -> a [label="1/2",color=red];
b -> b [label="2/1",color=blue];
}
可以使用命令列程式 dot 將此檔案轉換為其他格式。 例如,轉換為 svg
dot -Tsvg b.dot -o b.svg
影像檔案
- 帶有嵌入元資料的 png 影像
- 帶有嵌入元資料的 ppm 影像
- gif - 帶有嵌入元資料的 FractInt 輸出 http://www.nahee.com/spanky/www/fractint/fractint.html
- EXR 格式,OpenEXR,副檔名 .exr
OpenExr - 一種開放且非專有的擴充套件且高度動態範圍 (HDR) 影像格式,儲存 Alpha 和 Z 深度緩衝區資訊。
描述
exr 檔案格式
- 標準: OpenExr
- 副檔名:exr
- 顏色始終以場景線性顏色空間儲存,不會丟失任何資料。 這使得它們適合儲存渲染,這些渲染可以稍後進行合成、顏色分級並轉換為不同的輸出格式。[20]
- 檔案還可以包含實際上不是顏色的資料。 例如,法線貼圖或置換貼圖僅包含向量和偏移量。 此類影像應標記為非顏色資料,以便不會對它們進行顏色空間轉換。
程式
- exrtact - 用於操作 EXR 影像的各種工具
- HDR + WCG 影像檢視器 by Simon Tao
- Commons 中使用的影片格式
- GNU Parallel[21]
- 轉換影片
- ffmpeg2theora 引數列表
- 二次 Julia 集的影片
- 二次 Mandelbrot 集的影片
- FFMPEG 檔案格式
使用 BASH 和 Image Magic 將 pgm(或其他)靜態檔案轉換為動畫 gif:[22]
#!/bin/bash
# script file for BASH
# which bash
# save this file as g
# chmod +x g
# ./g
# for all pgm files in this directory
for file in *.pgm ; do
# b is name of file without extension
b=$(basename $file .pgm)
# convert from pgm to gif and add text ( level ) using ImageMagic
convert $file -pointsize 100 -annotate +10+100 $b ${b}.gif
echo $file
done
# convert gif files to animated gif
convert -delay 100 -loop 0 %d.gif[0-24] a24.gif
echo OK
# end
或者由 ClaudiusMaximus 提供的另一個版本[23]
for i in ??.svg
do
rsvg $i ${i%svg}png
convert ${i%svg}png ${i%svg}gif
done
gifsicle --delay 4 --loop --optimize ??.gif > out.gif
不要忘記: 12.5MP 限制 = 500 x 500 x 50 幀 = 600 x 600 x 34 幀 = 1000 x 1000 x 12 幀
從 pgm 到影片使用 Image Magic convert 的步驟
- pgm 檔案到 gif 檔案
- gif 檔案到影片
convert -delay 100 -loop 0 %d.gif[0-25] a25.mpg
#!/bin/bash
# script file for BASH
# which bash
# save this file as g
# chmod +x g
# ./g
i=0
# for all pgm files in this directory
for file in *.pgm ; do
# b is name of file without extension
b=$(basename $file .pgm)
# change file name to integers and count files
((i= i+1))
# convert from pgm to gif and add text ( Cx from name of file ) using ImageMagic
convert $file -pointsize 50 -annotate +10+100 $b ${i}.gif
echo $file
done
echo convert all gif files to one ogv file
ffmpeg2theora %d.gif --framerate 12 --videoquality 9 -o output129.ogv
echo b${i} OK
# end
可以從影像製作影片。 例如
使用 ffmpeg 建立 WebM 影片檔案[24][25]
ffmpeg -i x%08d.png -r 24 tifa.webm
或 ffmpeg2theora
ffmpeg2theora %d.gif --framerate 5 --videoquality 9 -f webm --artist "your name" -o otput.webm
如果您使用包含引數(此處為 Cx)的 名稱 檔案,那麼對檔案進行排序並製作影片會很容易
char name [10]; /* name of file */
i = sprintf(name,"%2.7f",Cx); /* result (is saved in i) but is not used */
char *filename =strcat(name,".pgm"); /* new name thru concatenate of strings */
- YUV4Mpeg 格式的影片檔案
- 壓縮成其他格式之前的原始影片[26]
- 元資料
- exif
- 註釋
- 塊
- ICC
- 單獨檔案
- 引數檔案
- 單獨文字檔案
顏色配置檔案 (ICC) 在影像中的儲存方式取決於影像格式
- 例如,在 PNG 中,它包含在 PNG iCCP 塊中
- 在 JPEG 中,它儲存在特定的“標記”中
- 對於其他影像格式,請參見 http://www.color.org/profile_embedding.xalter
- pngmeta[27]
使用 Image Magic
- 評論
- 轉義[29]
Image Magic 可以使用 mogrify 將評論新增到 png 影像中:[30]
mogrify -comment "My test comment" p.png
或使用 convert :[31]
convert in.png \
-set 'Copyright' 'CC-BY-SA 4.0' \
-set 'Title' 'A wonderful day' \
-set comment 'Photo taken while running' \
out.png
從 png 中讀取評論
identify -verbose p.png | grep -i "comment:"
comment: My test comment
或
identify -format "%c" X.ppm
塊是資訊片段,用於許多多媒體格式,例如 PNG、IFF、MP3 和 AVI。每個塊都包含一個標頭,它指示一些引數(例如塊型別、註釋、大小等)。中間有一個可變區域,包含由程式從標頭中的引數解碼的資料。 [32]
文字塊是標準輔助 PNG 塊之一。它的名稱是 tEXt。 [33]
PNG 文字塊的標準關鍵字
Title Short (one line) title or caption for image Author Name of image's creator Description Description of image (possibly long) Copyright Copyright notice Creation Time Time of original image creation Software Software used to create the image Disclaimer Legal disclaimer Warning Warning of nature of content Source Device used to create the image Comment Miscellaneous comment; conversion from GIF comment
ImageMagick 目前已知的輔助塊有 bKGD、cHRM、gAMA、iCCP、oFFs、pHYs、sRGB、tEXt、tRNS、vpAg 和 zTXt。
使用 **Image Magic 的 convert** 的示例
convert in.png -define png:include-chunk=tEXt file.txt out.png
可以使用 **pnmtopng** 實用程式
pnmtopng -text file.txt 1000.pgm > 1000.png
其中文字檔案 file.txt 為
Title Short (one line) title or caption for image Author Name of image's creator Description Description of image (possibly long) Copyright Copyright notice Creation Time Time of original image creation Software Software used to create the image Disclaimer Legal disclaimer Warning Warning of nature of content Source Device used to create the image Comment Miscellaneous comment; conversion from GIF comment
png-text-embaded[34]
儲存 pgm 檔案和一些影像描述的文字檔案
// save "A" array to pgm file and info txt file
int SaveArray2PGMFile( unsigned char A[], double k, char* text)
{
FILE * fp;
const unsigned int MaxColorComponentValue=255; /* color component is coded from 0 to 255 ; it is 8 bit color file */
char name [100]; /* name of file , error Naruszenie ochrony pamięci */
snprintf(name, sizeof name, "%f", k); /* */
char *filename =strncat(name,".pgm", 4);
char *comment="# ";/* comment should start with # */
/* save image to the pgm file */
fp= fopen(filename,"wb"); /*create new file,give it a name and open it in binary mode */
fprintf(fp,"P5\n %s\n %u %u\n %u\n",comment,iWidth,iHeight,MaxColorComponentValue); /*write header to the file*/
fwrite(A,iLength,1,fp); /*write A array to the file in one step */
printf("File %s saved. \n", filename);
fclose(fp);
// save info text filename
filename =strcat(name,".txt");
fp= fopen(filename,"wb");
fprintf(fp,"This image shows rectangle part of dynamic plane of discrete complex dynamical system z(n+1) = fc(zn) \n");
fprintf(fp," where fc(z)= z^2 + c \n");
fprintf(fp,"with numerical approximation of parabolic Julia set \n\n");
fprintf(fp,"parameter c is a root point between iPeriodParent = %d and iPeriodOfChild = %d hyperbolic components of Mandelbrot set \n", iPeriodParent , iPeriodChild);
fprintf(fp,"on the end of the internal ray of parent component of Mandelbrot set with angle = 1/%d in turns \n", iPeriodChild);
fprintf(fp," c = ( %f ; %f ) \n", Cx, Cy);
fprintf(fp," \n");
fprintf(fp,"critical point z = Zcr= ( %f ; %f ) \n", creal(Zcr), cimag(Zcr));
fprintf(fp,"parabolic alfa fixed point z = ZA = ( %f ; %f ) \n", creal(ZA), cimag(ZA));
fprintf(fp," radius around parabolic fixed point AR = %.16f ; Pixel width = %.16f \n", AR, PixelWidth);
fprintf(fp," iMaxN = %d ; ARn = %.16f \n",iMaxN, ARn); // info
fprintf(fp," EscapeRadius ER = %f ; \n", EscapeRadius);
fprintf(fp," Fatou coordinate U(Zcr) = Ux0 = %f ; \n", Ux0);
fprintf(fp," Maxima number of iterations : iMax = %d \n\n", iMax);
fprintf(fp," Image shows rectangular part of dynamic plane with %s\n", text);
fprintf(fp," from ZxMin = %f to ZxMax = %f\n", ZxMin, ZxMax);
fprintf(fp," from ZyMin = %f to ZyMax = %f\n\n", ZyMin, ZyMax);
fprintf(fp," iWidth = %d and iHeight = %d\n", iWidth, iHeight);
fprintf(fp," distortion = %f ; It should be 1.0 \n", ((ZxMax-ZxMin)/(ZyMax -ZyMin)/(iWidth/iHeight)));
if (t==0) fprintf(fp," No lost pixels : t = %d ; Parameters iMax and AR are good \n",t);
else fprintf(fp," Error : there are lost pixels : t > 0 ; you should increase iMax or make bigger AR \n\n");
fprintf(fp," computations made with double type numbers \n\n");
fprintf(fp,"use (k+AR) for file names where k is a number of file ; range(k) =[0,k] so there are (k+1) png files nad (k+1) text files \n\n");
fprintf(fp,"made with c console program \n");
//
printf("File %s saved. \n", filename);
fclose(fp);
return 0;
}
A parameter file is a small text file which contains all the settings required to produce a particular image ( Gnofract4D)
引數可以從引數檔案和影像檔案讀取 :[35]
引數檔案
- fct 副檔名由 Gnofract 4D 使用
- .fzs 副檔名由 Fractal Zoomer (二進位制檔案)使用
- F3 或 f3.toml 由 fractaler-3 程式 使用
- kfr 副檔名由 Kalles Fraktaler 2 http://www.chillheimer.de/kallesfraktaler/ 使用
- mdz 副檔名由 Mandelbrot Deep Zoom 使用
- mm 副檔名由 mightymandel 使用
- mmit 副檔名由 Mandel Machine 使用
- mp 副檔名由 mandelbrot-perturbator 使用
- m3p 副檔名由 Mandelbulb3D 使用
- par 副檔名由 Fractint 使用
- sft 副檔名由 SuperFractalThing 使用
- upr 副檔名由 UltraFractal 使用
- XML 副檔名由 David Eck Java 程式 用於儲存 Mandelbrot 設定
<mandelbrot_settings_2>
<image_size width="800" height="600"/>
<limits>
<xmin>-1.368156475175454059721</xmin>
<xmax>-1.368156475171886859735</xmax>
<ymin>0.001591278471916748399</ymin>
<ymax>0.001591278474592148387</ymax>
</limits>
<palette colorType="RGB">
<divisionPoint position="0" color="0.7909;0.9961;0.763"/>
<divisionPoint position="0.1667" color="0.8974;0.8953;0.6565"/>
<divisionPoint position="0.3333" color="0.9465;0.3161;0.1267"/>
<divisionPoint position="0.5" color="0.5184;0.1109;0.0917"/>
<divisionPoint position="0.6667" color="0.0198;0.4563;0.6839"/>
<divisionPoint position="0.8333" color="0.5385;0.8259;0.8177"/>
<divisionPoint position="1" color="0.7909;0.9961;0.763"/>
</palette>
<palette_mapping length="250" offset="96"/>
<max_iterations value="50000"/>
</mandelbrot_settings_2>
另請參見
/*
from gui main.c
https://gitorious.org/maximus/book/source/47ce485c4266b3d5fc62f685f001ce7606ce426f:
by
http://mathr.co.uk/blog/
loads txt file with parameters
http://qualapps.blogspot.com/2009/01/unicode-bom-handling-in-c-run-time.html
http://www.joelonsoftware.com/articles/Unicode.html
http://programmers.stackexchange.com/questions/102205/should-utf-16-be-considered-harmful
http://utf8everywhere.org/
http://www.codeguru.com/cpp/misc/misc/multi-lingualsupport/article.php/c10451/The-Basics-of-UTF8.htm
http://stackoverflow.com/questions/2113270/how-to-read-unicode-utf-8-binary-file-line-by-line
http://www.cl.cam.ac.uk/~mgk25/unicode.html
gcc l.c -lmpfr -lgmp -Wall
*/
#include <stdio.h>
#include <stdlib.h> // malloc
#include <string.h> // strncmp
#include <ctype.h> // isascii
#include <mpfr.h>
struct view {
mpfr_t cx, cy, radius, pixel_spacing;
};
static struct view *view_new() {
struct view *v = malloc(sizeof(struct view));
mpfr_init2(v->cx, 53);
mpfr_init2(v->cy, 53);
mpfr_init2(v->radius, 53);
mpfr_init2(v->pixel_spacing, 53);
return v;
}
static void view_delete(struct view *v) {
mpfr_clear(v->cx);
mpfr_clear(v->cy);
mpfr_clear(v->radius);
mpfr_clear(v->pixel_spacing);
free(v);
}
//http://stackoverflow.com/questions/5457608/how-to-remove-a-character-from-a-string-in-c?rq=1
// Fabio Cabral
void removeChar(char *str, char garbage) {
char *src, *dst;
for (src = dst = str; *src != '\0'; src++) {
*dst = *src;
if (*dst != garbage) dst++;
}
*dst = '\0';
}
//wikipedia : Serialization
// read data from file
static int deserialize(const char *filename) {
// open file in a text mode
FILE *in = fopen(filename, "r");
if (in) {
printf( "file %s opened\n", filename);
char *line = 0;
size_t linelen = 0;
ssize_t readlen = 0; // bytes_read = length of the line
// read line
while (-1 != (readlen = getline(&line, &linelen, in)))
{
//
if (readlen && line[readlen-1] == '\n') {
line[readlen - 1] = 0; }
// remove BOM
while (! isascii(line[0]))
{printf(" removed non-printing char = %c ( non -ASCII char ) = %3d (signed 8 bit) = %u (unsigned 8 bit) = 0x%.2X (hexadecimal) \n", line[0], line[0], (unsigned char) line[0], (unsigned char) line[0]);
removeChar(line,line[0]);
}
// size
if (0 == strncmp(line, "size ", 5))
{
printf( "size line found :");
int w = 0, h = 0;
sscanf(line + 5, "%d %d\n", &w, &h);
printf( "size of image in pixels : width = %d ; height = %d \n", w,h);
// resize_image(w, h); // FIXME TODO make this work...
}
// view
else if (0 == strncmp(line, "view ", 5))
{
printf( "view line found : \n");
int p = 53;
char *xs = malloc(readlen);
char *ys = malloc(readlen);
char *rs = malloc(readlen);
sscanf(line + 5, "%d %s %s %s", &p, xs, ys, rs);
struct view *v = view_new();
mpfr_set_prec(v->cx, p);
mpfr_set_prec(v->cy, p);
mpfr_set_str(v->cx, xs, 0, GMP_RNDN);
mpfr_set_str(v->cy, ys, 0, GMP_RNDN);
mpfr_set_str(v->radius, rs, 0, GMP_RNDN);
//
printf ("precision p = %d\n", p);
printf ("center = ");
mpfr_out_str (stdout, 10, p, v->cx, MPFR_RNDD);
printf (" ; ");
mpfr_out_str (stdout, 10, p, v->cy, MPFR_RNDD);
putchar ('\n');
printf ("radius = ");
mpfr_out_str (stdout, 10, p, v->radius, MPFR_RNDD);
putchar ('\n');
free(xs);
free(ys);
free(rs);
view_delete(v);
}
else if (0 == strncmp(line, "ray_out ", 8))
{
printf( "ray_out line found :\n");
int p = 53;
char *xs = malloc(readlen);
char *ys = malloc(readlen);
sscanf(line + 8, "%d %s %s", &p, xs, ys);
mpfr_t cx, cy;
mpfr_init2(cx, p);
mpfr_init2(cy, p);
mpfr_set_str(cx, xs, 0, GMP_RNDN);
mpfr_set_str(cy, ys, 0, GMP_RNDN);
free(xs);
free(ys);
mpfr_clear(cx);
mpfr_clear(cy);
}
else if (0 == strncmp(line, "ray_in ", 7)) {
printf( "ray_in line found : \n");
int depth = 1000;
char *as = malloc(readlen);
sscanf(line + 7, "%d %s", &depth, as);
free(as);
}
else if (0 == strncmp(line, "text ", 20)) {
printf( "text line found : \n");
//int p = 53;
char *xs= malloc(readlen);
char *ys = malloc(readlen);
char *ss = malloc(readlen);
sscanf(line + 20, "%s %s %s \n", xs, ys, ss);
free(xs);
free(ys);
free(ss);
}
else if (0 == strncmp(line, "//", 2 )) {
printf( "line of comment found : %s\n", line );
}
else printf( "not-known line found ! Maybe line with BOM ? \n");
} // while
free(line);
fclose(in);
printf( "file %s closed\n", filename);
return 0;}
// if (in)
else {
printf( "file %s not opened = error !\n", filename);
return 1;}
}
int main (int argc, const char* argv[])
{
if (argc != 2) {
fprintf(stderr, "program opens text file \n");
fprintf(stderr, "program input : text file with parameters \n");
fprintf(stderr, "usage: %s filename\n", argv[0]);
return 1;
}
deserialize(argv[1]);
return 0;
}
這個程式
- 開啟二進位制 ppm (P6) 或 pgm (P5) 檔案
- 它不開啟這些檔案的 ASCII 版本。
它可用於透過檢查滑鼠移動時控制檯中的輸出來檢查影像。將您的程式碼新增到 Motion 函式並更新 Zxmin 和 Zymin(世界座標)。
它不適用於最新版本的 OpenGl。
/*
* image.c
*
* read in a PPM or PGM binary image and display it, full size
Based on code by :
Dr. Lori L. Scarlatos
Stony Brook University
http://ms.cc.sunysb.edu/~lscarlatos/
"I do not have a license for image.c;
it was created as an example for my students.
Please feel free to use it.
Best regards,
Lori"
* ----------------------------
* it does not opens asci versions of these files
* examples files :
* http://people.sc.fsu.edu/~jburkardt/data/data.html
http://web.eecs.umich.edu/~sugih/courses/eecs487/glut-howto/sample.c
// gcc v.c -lm -lGLU -lglut -Wall // ? windows
gcc v.c -lm -lglut -lGL -lGLU -Wall // ubuntu
./a.out 5.pgm
*/
/*
locate glut.h
/usr/include/GL/freeglut.h
/usr/include/GL/glut.h
#ifdef FREEGLUT
#include <GL/freeglut.h>
#else
#include <GL/glut.h>
#endif
*/
//#include <Windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
//#include <GL/glut.h> // oryginal glut
#include <GL/freeglut.h> // freeglut
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h> /* fabs*/
//#include <malloc.h>
/* Global variables */
#define MAXLINE 80 /* maximum length of a line of text */
/*
3.2 Conventions
In developing the freeglut library, we have taken careful steps to ensure consistency in function operation across the board,
in such a manner as to maintain compatibility with GLUT's behavior whenever possible. In this section some of the important conventions of FreeGLUT,
and their compatibility with GLUT, are made explicit.
3.2.1 Window placement and size
There is considerable confusion about the "right thing to do" concerning window size and position. GLUT itself is not consistent between Windows and UNIX/X11;
since platform independence is a virtue for freeglut, we decided to break with GLUT's behaviour.
Under UNIX/X11, it is apparently not possible to get the window border sizes in order to subtract them off the window's initial position until some time after the window has been created.
Therefore we decided on the following behavior, both under Windows and under UNIX/X11:
When you create a window with position (x,y) and size (w,h), the upper left hand corner of the outside of the window (the non-client area) is at (x,y) and the size of the drawable (client) area is (w,h).
The coordinates taken by glutInitPosition and glutPositionWindow, as well as the coordinates provided by FreeGLUT when it calls the glutPositionFunc callback, specify the top-left of the non-client area of the window.
When you query the size and position of the window using glutGet, FreeGLUT will return the size of the drawable area
--the (w,h) that you specified when you created the window
--and the coordinates of the upper left hand corner of the drawable (client) area
--which is NOT the (x,y) position of the window you specified when you created it.
*/
GLint ImageWidth, ImageHeight; /* size of the Image in pixels */
GLint WindowWidth, WindowHeight; /* size of the window in pixels */
GLint MaxScreenWidth, MaxScreenHeight; /* size of the screen in pixels */
GLubyte *Picture; /* Array of colors (GLubyte) */
int size;
// mouse position as a global variables
//static float mx=0.0f,my=0.0f ;
int iX, iY; //
int centerX = 200, centerY = 200;
GLint iYmax,iXmax; // mouse coordinate inside image
unsigned char pixel[3];
// change it manually !!!!!
const double ZyMin=-1.0;
const double ZxMin=-2.0;
const double PixelHeight=0.0020010005002501 ;
const double PixelWidth=0.0020010005002501 ;
int filetype;
enum {P2, P3, P5, P6}; /* possible file types */
/* gives position of point (iX,iY) in 1D array ; uses also global variables */
unsigned int f(unsigned int _iX, unsigned int _iY)
{return (_iX + (iYmax-_iY-1)*iXmax );}
/*
* Read from a PPM or PGM (binary) file
* Output is a array of GLubyte
*/
void readPPM (char *filename, GLubyte **pic) {
FILE *fp;
char line[MAXLINE];
int i, rowsize;
// int size; // moved to global var
int j ;
GLubyte *ptr;
/* Read in file type */
fp = fopen(filename, "r"); /* in Unix rb = r */
if (fp==NULL) {perror(" perror : " ); printf("Error from fopen : I can't open %s file' ! ", filename); exit(1); }
else printf("File %s has been opened !\n", filename);
/* Each file starts with aa two-byte magic number (in ASCII) that explains :
* - the type of file it is (PBM, PGM, and PPM)
* - its encoding (ASCII or binary).
* The magic number is a capital P followed by a single digit number.
*/
fgets (line, MAXLINE, fp); /* 1st line : Magic Number */
switch (line[1])
{
case '2':
filetype = P2;
printf("This is PGM text file (P2), but now I do not have procedure for opening it \n");
break;
case '3' :
filetype = P3;
printf("This is PPM text file (P3), but now I do not have procedure for opening it !\n");
break;
case '5':
filetype = P5;
printf("This is PGM binary file (P5) and I can open it !\n");
break;
case '6' :
filetype = P6;
printf("This is PPM binary file (P6) and I can open it !\n");
break;
default :
printf("Error from readPPM : need binary PPM or binary PGM file as input!\n");
exit(1);
}
/* if this is a comment, read next line. Maybe in binary files there is no comment ?*/
/* there maybe more then one line of comment */
fgets (line, MAXLINE, fp);
while (line[0]=='#')
{ printf(" comment = %s \n", line); /* 2nd or more line starting with # = comment, print it */
fgets (line, MAXLINE, fp); // read next line
}
/* Read in width and height, & allocate space */
/* these 2 numbers should be in one line with space between them */
/* 3nd line: width and height */
sscanf(line, "%d %d", &ImageWidth, &ImageHeight);
printf ("iWidth = %d\n", ImageWidth);
printf ("iHeight = %d\n", ImageHeight);
iXmax=ImageWidth-1;
iYmax=ImageHeight-1;
if (filetype == P5) {
size = ImageHeight * ImageWidth; /* greymap: 1 byte per pixel */
rowsize = ImageWidth;
}
else /* filetype == P6 */ {
size = ImageHeight * ImageWidth * 3; /* pixmap: 3 bytes per pixel */
rowsize = ImageWidth * 3;
}
*pic = (GLubyte *)malloc (size); /* create dynamic array */
/* Read in maximum value (ignore) */
fgets (line, MAXLINE, fp); /* next line */
/* */
if (filetype==P5 || filetype==P6){
/* Read in the pixel array row-by-row: 1st row = top scanline */
ptr = *pic + (ImageHeight-1) * rowsize;
for (i = ImageHeight; i > 0; i--) {
/* For binary File I/O you use fread and fwrite */
j = fread((void *)ptr, 1, rowsize, fp);
ptr -= rowsize;
}
if (j) printf("File %s has been read !\n", filename);
else printf(" j Error from readPPM procedure : I can't read %d file !.\n", j);
}
else printf("Error from readPPM procedure : I can't read %s file !. It should be P5 or P6 file !\n", filename);
fclose(fp);
printf("File %s has been closed !\n", filename);
}
/* Draw the picture on the screen */
void Draw(void) {
/* black background of GLUT window */
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear the background of our window to black
glClear(GL_COLOR_BUFFER_BIT); //Clear the colour buffer (more buffers later on)
glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations
glFlush(); // Flush the OpenGL buffers to the window
// left lower corner of displayed image
glRasterPos2i(-1,-1); // By default, OpenGL assumes a system running from -1 to 1,
switch (filetype){
case P5 : /* greymap: use as illumination values */
glDrawPixels(ImageWidth, ImageHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, Picture);
printf("P5 Image has been drawn !\n");
break;
case P6 :
glDrawPixels(ImageWidth, ImageHeight, GL_RGB, GL_UNSIGNED_BYTE, Picture);
printf("P6 Image has been drawn !\n");
break;
default :
printf("Error from Draw procedure : There is no image to draw !\n");
}
}
// Detecting Mouse Clicks
// x and y specify the location (in window-relative coordinates) of the mouse when
// the event occurred
void MouseClicks (int button, int state, int x, int y)
{
switch (button)
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
// do something
case GLUT_RIGHT_BUTTON: ;
// etc., etc.
}
// mouse motion
//The x and y callback parameters
// indicate the mouse location
// in window relative coordinates
//
// x, y –> coordinates of the mouse relative to upper left corner of window
// setting the mouse position to be relative to the mouse
// position inside the window
//
void PassiveMouseMotion(int x, int y) {
//double Zx,Zy;
//double Ux;
//int index;
//GLubyte Gray;
// put your code here ????
iX = x;
/* invert y axis */
iY = WindowHeight - y -1 ; //+ (glutGet(GLUT_WINDOW_HEIGHT) - ImageHeight); ///glutGet(GLUT_WINDOW_HEIGHT) - y; // ????
/* output : prints to console */
if ((filetype==P5 || filetype==P6) && -1<iX && iX< ImageWidth && iY<ImageHeight) // && iY<ImageHeight
{
glReadPixels(iX, iY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
// pixel coordinates of the mouse relative to upper left corner of window
printf(" pixel iX=%3d / %d ; iY=%3d color = %d \n", iX, MaxScreenWidth, iY, pixel[1] );
}
}
static void Key(unsigned char key, int x, int y)
{
switch (key) {
case 27 : {glutLeaveFullScreen(); break;}/* esc */
case 'f': {glutFullScreen(); break; }
case 'q': {printf("Key preseed and exit \n"); exit(1) ;}
case 'Q': {printf("Key preseed and exit \n"); exit(1) ;}
case 't': {glutFullScreenToggle(); break; } // GLUT does not include the glutLeaveFullScreen and glutFullScreenToggle functions from freeglut
default: return ;
}
}
/*
Resize the picture ; OpenGL calls this function whenever the window is resized
Called when window is resized, also when window is first created, before the first call to display().
*/
void Reshape(GLint w, GLint h) {
/* save new screen dimensions */
WindowWidth = w;
WindowHeight = h;
/* the viewport is the rectangular region of the window where the image is drawn */
// Viewport : A rectangular region in the screen for display (in screen coordinate system)
glViewport(0, 0, ImageWidth-1, ImageHeight-1); // glViewport( 0.f, 0.f, SCREEN_WIDTH, SCREEN_HEIGHT );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Define a world window : A rectangular region in the world that is to be displayed (in world coordinate system)
// By default, OpenGL assumes a system running from -1 to 1,
gluOrtho2D(-1, 1, -1, 1); // An orthographic projection is basically a 3D projection that does not have perspective
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/*
Initialization: create window
glutInitWindowSize(600, 600);
*/
void MyInit(int argc, char *argv[]) {
char filename[MAXLINE];
/* Read in the file (allocates space for Picture) */
if (argc < 2)
{
printf ("Enter the name of a binary PPM or PGM file: ");
scanf("%s", filename);
readPPM ((char *)filename, &Picture);
}
else { readPPM (argv[1], &Picture); }
glutInit(&argc, argv);
MaxScreenWidth = glutGet(GLUT_SCREEN_WIDTH);
MaxScreenHeight = glutGet(GLUT_SCREEN_HEIGHT);
glutInitWindowPosition(-1, 1); // upper left corner
glutInitWindowSize(MaxScreenWidth, MaxScreenHeight ); // full screen of my monitor
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
if (glutCreateWindow("OpenGl binary pgm/ppm Image viewer ") == GL_FALSE)
{printf("Error from MyInit , glutCreateWindow\n"); exit(1);}
}
/* ------------------ Main program ---------------------------------------*/
int main(int argc, char **argv)
{
MyInit(argc, argv);
glutPassiveMotionFunc(PassiveMouseMotion); // mouse move with no key pressed
glutReshapeFunc(Reshape); // move or resize of screen window
glutDisplayFunc(Draw); //
glutKeyboardFunc(Key);
//
glutMainLoop();
return 0;
}
- ↑ Artem Dudko 和 Michael Yampolsky 的 Feigenbaum Julia 集的可計算性
- ↑ admvfx : Benjamin Seide 的檔案格式和位深度
- ↑ a b "AV1 Image File Format (AVIF)". AOMediaCodec.GitHub.io. Archived from the original on 29 November 2018. Retrieved 25 November 2018.
- ↑ Mavlankar, Aditya; De Cock, Jan; Concolato, Cyril; Swanson, Kyle; Moorthy, Anush; Aaron, Anne (2020-02-13). "AVIF for Next-Generation Image Coding". The Netflix Tech Blog. Archived from the original on 2020-02-15. Retrieved 2021-11-19.
- ↑ "AOMediaCodec / av1-avif". GitHub. Retrieved 2022-02-05.
- ↑ a b Concolato, Cyril (2019年10月14日). "AV1 Image File Format (AVIF)" (PDF). AOMedia. Archived (PDF) from the original on 5 November 2019. Retrieved 6 November 2019.
- ↑ "Film Grain Synthesis for AV1 Video Codec" (PDF). Archived (PDF) from the original on 7 January 2021. Retrieved 14 December 2020.
- ↑ 位深度色彩精度在光柵影像中 (Denis Kozlov 著)
- ↑ 計算機語言基準測試遊戲
- ↑ Nayuki 的可移植浮點對映格式 I/O Java
- ↑ imagemagick : 高動態範圍
- ↑ HDR by Josef Pelikán & Alexander Wilkie
- ↑ [:w:Raw image format|維基百科中的原始影像格式]
- ↑ 維基百科:二進位制檔案
- ↑ 維基百科:影像檔案格式 - 光柵格式
- ↑ 分形影像壓縮的並行實現 By Ryan F. UYS
- ↑ rawpedia - RawTherapee、raw 拍攝和所有 raw 內容的百科全書
- ↑ itsfoss : Linux 上的 raw 影像工具
- ↑ photo.stackexchange 問題:TIFF 的質量真的比 PNG-24 高嗎?
- ↑ blender 手冊:色彩管理
- ↑ Gnu Parallel
- ↑ Fritz Mueller 的梅比烏斯變換動畫 GIF
- ↑ ReCode 專案 - ClaudiusMaximus 的地形形式動畫
- ↑ Mukund 的製作影片方法
- ↑ Yannick Gingras 的 Lisp 中的 mini-fract
- ↑ fileinfo : 副檔名 y4m
- ↑ pngmeta
- ↑ PNG 和 exif
- ↑ Image Magic - escape
- ↑ Stackoverflow : 如何向 PNG 新增額外的元資料?
- ↑ Stackoverflow : 如何將文字塊插入 PNG 影像?
- ↑ 維基百科 : 塊(資訊)
- ↑ PNG(行動式網路圖形)規範,版本 1.2 : 塊
- ↑ https://github.com/gbenison/png-text-embed
- ↑ Mightymandel 文件