当前位置:网站首页>Qimage image format summary
Qimage image format summary
2022-07-18 13:38:00 【Progress every day 2015】
Um. , This QImage For a long time , It didn't work for a while , Forget , I've been asked twice , All of a sudden, I can't explain it clearly , I'm ashamed , I think it's necessary to sum it up again , Otherwise, I will be shameless to myself .
The image data is saved in bytes , The number of bytes per line must be 4 Integer multiple , The lack of fill 0.
( Because we're using 32 operating system , So the data is based on 32 Bit aligned , So the number of bytes per line must be 4 That is, the data bits of each row must be 32 Integer multiple of bits .) Here is according to my understanding , It seems wrong , Fix it , I've been looking at data alignment recently , This passage ignores , Not deleted , Because , Want to leave a footprint , I'll post it when I find the right answer . however , The data of the image is indeed according to 32 Bit aligned .
If it's not an integer multiple , According to the formula : W = ( w * bitcount + 31 )/32 * 4;
notes : w Is the width of the image ,bitcount Is the bit depth of the image , namely 32、24 etc. , Calculated W Is the number of bytes per line of the image in the program .
Here's the story QImage Of 32、24、8 Bitmap .
Image format :QImage::Format_RGB32 ,QImage::Format_RGB888,QImage::Format_Indexed8.
Construct an image :
(1)、QImage myImage1 = QImage(filename); Open the image according to the file name , If the image itself is 32、24 Bit , The image in the program is 32 Bit , If the image itself is 8 position 、1 Bit , The program corresponds to 8 position 、1 position .
(2)、QImage myImage2 = QImage(width, height, QImage::Format_…); Construct an image according to the width and height of the image , The program will automatically align the image data according to the image format .
Manipulating images : according to (2) Construct the image in a way , stay Debug Next , If you don't give the image myImage2 initial value , The image is not black , but release Next , The constructed image defaults to black .
Okay , Now we need to operate on image data ,32 Bit images are undoubtedly the simplest , Because its data is aligned . use width Represents the width of the image ,height Represents the height of the image .
First, be familiar with a few functions :
a、uchar* bits(); You can get the first address of the image
b、int byteCount(); The total number of bytes of the image
c、int bytesPerLine(); Number of bytes per line
1、QImage::Format_RGB32, The deposit format is B,G,R,A Corresponding 0,1,2,3
QImage::Format_RGB888, The deposit format is R, G, B Corresponding 0,1,2
QImage::Format_Indexed8, You need to set the color table ,QVector<QRgb>
Gray image color table setting :
QVector<QRgb> colorTable;
for(int k=0;k<256;++k)
{
colorTable.push_back( qRgb(k,k,k) );
}
2、QImage p_w_picpath32 = QImage(width, height, QImage::Format_32);
QImage p_w_picpath24 = QImage(width, height, QImage::Format_24);
QImage p_w_picpath8 = QImage(width, height, QImage::Format_8);
p_w_picpath8.setColorTable(colorTable);
3、 Need to take each pixel for processing , Use pointer value , The way of line scanning :
int lineNum_32 = 0; // Row number
int pixelsub_32 = 0; // Pixel subscript
uchar* p_w_picpathbits_32 = p_w_picpath32.bits(); // Get the first address of the image ,32 Bitmap
uchar* p_w_picpathbits24 = p_w_picpath24.bits();
uchar* p_w_picpathbits8 = p_w_picpath8.bits();
for(int i=0; i<height; ++i)
{
// According to the usual understanding , We will deal with it as follows , Take each line
lineNum_32 = i * width * 4; // For any image , There is no problem with this sentence
// lineNum_24 = i * width * 3; //?? When width No 4 The integral times of , This sentence doesn't start on every line
// lineNum_8 = i * width; //?? When width No 4 The integral times of , This sentence doesn't start on every line
for(int j=0; j<width; ++j)
{
int r_32 = p_w_picpathbits_32[ lineNum_32 + j * 4 + 2];
int g_32 = p_w_picpathbits_32[ lineNum_32 + j * 4 + 1];
int b_32 = p_w_picpathbits_32[ lineNum _32 + j * 4];
// int r_24 = p_w_picpathbits_24[ lineNum_24 + j * 3]; // Pay attention to differences 32 Bit graph
// int g_24 = p_w_picpathbits_24[ lineNum_24 + j *3 + 1];
// int b_24 = p_w_picpathbits_24[ lineNum_24 + j * 3 + 2];
// int gray_8 = p_w_picpathbits_8[ lineNum_8 + j];
……
// My own operation
}
}
//?? Something is wrong. , Because the actual image data is not based on width Is of true width , solve , There are two ways :
The first method : Calculate the actual width by yourself
It is amended as follows :
// Get the number of bytes per line
int W_32 = ( width * 32 + 31 )/32 * 4; // Note that there is no rounding here , So don't convert at will
int W_24 = ( width * 24 + 31 )/32 * 4;
int W_8 = ( width * 8 + 31)/32 * 4;
// You can also use QT Function to get , The function is the same as above
{
int W_32 = p_w_picpath32.bytesPerLine();
int W_24 = p_w_picpath24.bytesPerLine();
int W_8 = p_w_picpath8.bytesPerLine();
}
for(int i=0; i<height; ++i)
{
// Now we can follow the usual understanding , Take each line
lineNum_32 = i * W_32; // Be careful , There's no need to multiply here (4, 3 etc. )
// lineNum_24 = i * W_24;
// lineNum_8 = i * W_8;
for(int j=0; j<width; ++j)
{
// The operation here is the same as that above
}
}
The second method : use scanLine(int) To get the first address of each line ,
for(int i=0; i<height; ++i)
{
p_w_picpathbits_32 = p_w_picpath32.scanLine(i);
p_w_picpathbits_24 = p_w_picpath24.scanLine(i);
p_w_picpathbits_8 = p_w_picpath8.scanLine(i);
for(int j=0; j<width; ++j)
{
int r_32 = p_w_picpathbits_32[ j * 4 + 2];
int g_32 = p_w_picpathbits_32[ j * 4 + 1];
int b_32 = p_w_picpathbits_32[ j * 4];
// int r_24 = p_w_picpathbits_24[ j * 3];
// int g_24 = p_w_picpathbits_24[ j *3 + 1];
// int b_24 = p_w_picpathbits_24[ j * 3 + 2];
// int gray_8 = p_w_picpathbits_8[ j ];
……
// My own operation
}
}
OK, The index of the above two methods will not have the problem of image data offset
4、 Notice that QImage The constructor of ,QImage::QImage ( uchar * data, int width, int height, Format format )
Um. , This function starts from uchar* To construct an image , Generally, we may store the image data first uchar* in ,
uchar* data32 = new uchar[ width * height * 4];
uchar* data24 = new uchar[ width * height * 3];
uchar* data8 = new uchar[ width * height];
from data32 Construct an image , There will be no problem , But when width No 4 The integral times of , You can't start from data24 and data8 Construct the data you want , The program will hang up , Because the data volume of these two arrays is not enough for one picture at all ( Remember if the data is complete ).
terms of settlement :
You need to first calculate , The amount of real data in your image ( Number of bytes ), According to QImage.byteCount() Function to get the number of bytes of the image , Of course , You can also calculate by yourself , Calculation formula byteCount = height * W; there W Is the number of bytes per line , Its calculation method has been described above .
then , You can choose from QByteArray To get the converted pointer data :
Such as : Put your image data in an array uchar* srcData; in
QByteArray p_w_picpathByteArray = QByteArray( (const char*)srcData, byteCount );
uchar* transData = (unsigned char*)p_w_picpathByteArray.data();
QImage desImage = QImage(transData, width, height, QImage::Format_…);
Um. , After the above conversion ,transData Will be an array of complementary data , The image thus constructed will not have any problems .
Okay , It's over , There are many small problems , I don't want to write , It should be enough , If you have specific other questions , Think again , It must be solved , ha-ha
边栏推荐
- DzzOffice_ Flowplayer player changes
- Recursively solve the traversal of binary trees (often test basic examples)
- Dls-42/4-4 dc110v double position relay
- 探索式软件测试
- u盘删除的文件怎么恢复
- [software testing] 08 -- black box testing method (boundary value analysis method, cause and effect diagram and decision table method)
- 2022-07-信息论-吴军
- leetcode - 面试题 02.05. 链表求和
- Some points for attention in drawing excel charts
- Sword finger offer 26 Substructure of tree
猜你喜欢
![03_ Case setup [resttemplate calls microservices]](/img/67/98814e8762e0198aa6368575678f4d.png)
03_ Case setup [resttemplate calls microservices]

static变量看着有点晕,gdb汇编清醒清醒

Sword finger offer 18 Delete the node of the linked list

Three horses join hands with Qianyuan public welfare foundation | cool in summer, pay tribute to the adherents!

Laravel excel exports data, modifies the style of data, and processes data

Dls-12b/dc220v double position relay

leetcode - 面试题 02.05. 链表求和
![[TinyML]APQ:Joint Search for Network Architecture, Pruning and Quantization Policy](/img/6f/5f0e16ae3ddaa45b3c2c0e81c50470.png)
[TinyML]APQ:Joint Search for Network Architecture, Pruning and Quantization Policy

Dpdk flow filter summary (flow director/ rte_flow)

singan:learning a generative model from a single natural image
随机推荐
Basic UNIX domain protocol programming
DLS-12B/DC220V双位置继电器
312312dd
探索式軟件測試
求水仙花数
Sword finger offer 26 Substructure of tree
static变量看着有点晕,gdb汇编清醒清醒
Tools to measure the gap between two distributions: cross entropy and KL divergence
C# default
Detailed explanation of some functions with similar functions in MySQL
Sword finger offer 11 Rotate the minimum number of the array
Sword finger offer 63 Maximum profit of stock
[TinyML]APQ:Joint Search for Network Architecture, Pruning and Quantization Policy
猜数字大小II[动态规划解决什么问题?]
ORA-19625异常处理记录
u盘删除的文件怎么恢复
A row of "cranes" in the clear sky: Chinese flying cranes with numbers as wings
视频处理:视频抽样
单细胞文献学习(part4)--SCANPY: large-scale single-cell gene expression data analysis
Sword finger offer 10- ii Frog jumping on steps