Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从给定的图像数据中提取像素数据。需要帮助理解代码吗_C++_Image Processing_Bit Manipulation_Bit Shift - Fatal编程技术网

C++ 从给定的图像数据中提取像素数据。需要帮助理解代码吗

C++ 从给定的图像数据中提取像素数据。需要帮助理解代码吗,c++,image-processing,bit-manipulation,bit-shift,C++,Image Processing,Bit Manipulation,Bit Shift,我一直在研究从图像数据构建纹理,但是一些教程中提供的代码处理移位以获得图像像素。然而,我是一个非常新的位转移。我理解二进制的&和|,但我不知道为什么需要这个代码来获取像素数据 以下是纹理数据: static char* g_pTextureData = "?VE`8U)K13Y:1C];2$%:5DQA>'&!@WB*:UQR9EET9%ES8UAP9UMZ>&%[A6Z$>6-Z" "S[6XR[*PIH2\"IXN0HY2>DWR#VL;+TL

我一直在研究从图像数据构建纹理,但是一些教程中提供的代码处理移位以获得图像像素。然而,我是一个非常新的位转移。我理解二进制的
&
|
,但我不知道为什么需要这个代码来获取像素数据

以下是纹理数据:

static char* g_pTextureData =
  "?VE`8U)K13Y:1C];2$%:5DQA>'&!@WB*:UQR9EET9%ES8UAP9UMZ>&%[A6Z$>6-Z"
  "S[6XR[*PIH2\"IXN0HY2>DWR#VL;+TL3,LYZ<QZVNUL\"_L)..NJJXN:>[V<#)R;\"Y"
  "W\\G,Y-/4P9^3SZ^KZ-K>RJN?S:VMY=/4U[NPW<+![-GCV<\"UX,C&Y-7BZ=K>V\\2^"
  "W\\F^XL[!R*.6UK:PYM7/RZB:U[R^V;^POY:)SZ^:Y]#/Y=')SZ^:Y]#/Y=')UKBH"
  "OY*%O9*%K()WPYF+Q)Z+JGUVU[RUO9.\"HW=MN9)\\R)N)MXQVM9!WRIN+QIJ+L8-W"
  "GG9FJGYNIGMMJ'YMK()PHWIKN9J+HX)GGGI?L8YQL8US@653F7EBJGYJJGUIEVU@"
  "GGY:F7E9E'18G'I9G'M:E'1;CW->C')6AVE3E'==F7ED<UQ5@6M4EWE5F7Y6DG92"
  "C'!6AVI5@613AVQ5B6U5@6=6?FA8?F96>V)5@6E6AVY<:UE6:UM1>V90@6E0@6A0"
  "<U]7=E]7<UE6<%M7=F!7<%M5:5=4:5M7;EI6:UM2;EY29%138E53:UA1:5A0<%]2"
  "9%E6<%U:;EE;;EA::UE79E548E%39%15:5957U)29E=58E-69EA6<%Y6<%Y6:5E5"
  "6U)3:UY<=F5A<U]?=F1>:UI:9EA7:5E78E158E-6;EQ89E=69%54:5M6<V189%E6"
  "4$I/7556;F->;F!?;EY>:UI=;EY=<&%=9%588E-59%55<&!;:5A96TY25DY/5D]0"
  "/SQ*03],1D-/2$523$)44$-65DI76TY86TQ674Y674Y49EA::5E;64Y2/SQ(/CQ("
  ",#%'+C!',#))-#-,-S--.3-./#9//#9./#1-0SM02D%013U,/SA*-S-(+BY%,3!&"
  "(R-%&Q]$&A]%'B)'(R1()\"5((B-(*2=(*\"9)+\"E)+2M))21%(\"%#'!Y#(\"%$(B)%"
  "\"A)\"\"A)\"\"1-\"\"A-\"\"A1\"\"A-\"\"Q-\"#!5\"#A5\"#A5\"#Q9\"$AA"
  "\"&QU$%QM#\"Q-\"\"A-\""
  "";
接下来是十进制值为86的V 对于宏,86-33=53 然后右移4位

(00000000 00000000 00000000 00110101) >> 4
(00000000 00000000 00000000 00001101) = 13
然后我们做一个按位or运算

01111000
00001101
========
01111101 = 125
我明白这背后的道理。但我的问题是为什么需要数学?为什么33和位移动?还有,为什么我们需要0xF和0x3

它正在解压缩图像数据吗?还是它在做别的事情

这是我需要知道的吗?或者这只是一个非常具体的例子,因为这就是我们压缩/解压缩图像的方式

更新,谢谢@v154c1帮我把这个放进包里。

对于任何遇到这个的人。这就是我如何使用@v154c1演示的内容对其进行合理化的

00rrrrrr << 2 = rrrrrr00
00rrgggg >> 4 = 000000rr
rrrrrr00 | 000000rr = rrrrrrrr

00rrgggg & 00001111 = 0000gggg << 4 = gggg0000
00ggggbb & >> 2 = 0000gggg
gggg0000 | 0000gggg = gggggggg

00ggggbb & 00000011 = 000000bb << 6 = bb000000
00bbbbbb
bb000000 | 00bbbbbb = bbbbbbbb
00rrrr>4=000000rr
RRRRRR 00 | 000000 RR=RRRRRR
00rrgggg&00001111=0000GGGGGG>2=0000gggg
gggg0000 | 0000GGGGGG=GGGGGGGGGG

00ggggbb&00000011=000000bb罗杰·罗兰()给出的答案实际上很好地解释了这一点。 它们以4个可打印字符存储RGB值(24位)

魔法值
33
是他们使用的第一个可打印字符(
,ASCII格式)

因此GIMP完成的过程是:

首先,您有1个像素,其中R、G和B的值为3个8位。您可以将其成像如下:

rrrrrrrr gggggggg bbbbbbbb

但您不能简单地将其转储到头文件中。所以你把它分成6位的组:(值0-63):

然后将数字
33
添加到每个组中(因此值为33-96),然后将其作为4个字符存储到头文件中

为了将其解码回像素数据,只需减去33即可得到原始的6位值,然后再将这些位组合成3个8位值

这种移位和掩码(
&
)只是将位组合在一起

例如,以第一个为例:

pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4));
然后换档将值推到正确的位置:

rrrrrr << 2  = rrrrrr00
rrgggg >> 4  =       rr

您已经收到“主要问题”的答案,因此我将回答其他问题。:-)

它正在解压缩图像数据吗?还是它在做别的事情

您所看到的是一个。压缩是一种编码,但这不是压缩

考虑一下,如果我告诉你,你需要给我一个4到9之间的号码。但是,如果我告诉你,你只能用符号集
A
B
C
,怎么办。如果你只是想在头顶上做点什么,你可以选择:

 4 => A
 5 => B
 6 => C
 7 => AA
 8 => BB
 9 => CC
当然,可能还有其他编码。有些可能更容易阅读和理解,可能是“浪费”:

无论是从左边看还是从右边看,在“抽象”中仍然只有6个不同的值。将保留相同数量的数据。但是你只需要看看你的屏幕就知道如果我们要用字符数来衡量它,而不是用状态来衡量它,它已经变长了

这就是图像数据在这种情况下发生的情况。您将获取三个字节的像素数据,并将其存储在有限集合中的四个字节大小的字符中。因为一个像素和一个字符都占用一个字节,所以可以将其视为“变大”

(但在某种程度上,它实际上不是。)

这是我需要知道的吗?或者这只是一个非常具体的例子,因为这就是我们压缩/解压缩图像的方式

我想说,你“需要”知道什么完全取决于你“想要”完成什么。:-)


但是如果你想成为一名程序员,理解编码的抽象点是很重要的。人们可以把整个职业生涯都花在软件上,而不必接触C(有些人可能会说你很可能是)。然而,我在回答中提到的关于编码的概念无论你用什么编程都会出现。

但是,这篇回答中提供的答案的可能重复并不能满足我的问题。“但你不能简单地将其转储到头文件中。”为什么不呢?@Stealthguy:因为8位值可以变成ASCII格式的任何内容。因此,可能是某个字符弄乱了输出(例如,
”-这会过早终止字符串),也可能是某个字符在C/C++源代码中根本无效(如值为0的字符)。通常只有一部分ASCII字符可以在源代码中使用。哦,我明白了。这就是为什么我们需要在其中添加!的原因。我刚看了一张ASCII图表,发现33之前的所有字符都是不可读的。这现在是有意义的。不过,仍在处理其余的答案。好的,我想我现在完全理解了。ThaNKS@ V154C1HY@ HostileFork,谢谢你的解释。我确实把自己当成程序员,我是一个软件工程师。但是我主要工作在高级编程上,从来都不需要涉入一些肮脏的东西。但是我潜入了程序生成之类的东西。多亏了你们这些家伙,赶快把它捡起来。@Stealthguy没有轻视的意思……我只是说,我认为问题中唯一真正“任何程序员都需要知道”的地方是“编码是什么?”“.软件中有很多东西需要学习,而其他人则担心知道任意的符号选择,如
&
|
。。。或者所有C不能保证的基本东西,例如::-)哦,我没看错。我还有很多东西要学。我知道编码之类的。我理解编码的基本思想,只是不理解其中的细节。谢谢
pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4));
data[0] - 33 = rrrrrr
data[1] - 33 = rrgggg
rrrrrr << 2  = rrrrrr00
rrgggg >> 4  =       rr
!, ", #, $, %, &, \', (, ), *, +, ,, -, ., /, 0, 1, 2, 3, 4, 5, 6, 7, 8,
9, :, ;, <, =, >, ?, @, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P,
Q, R, S, T, U, V, W, X, Y, Z, [, \\, ], ^, _, `
 4 => A
 5 => B
 6 => C
 7 => AA
 8 => BB
 9 => CC
 4 => AAAA
 5 => AAAAA
 6 => AAAAAA
 7 => AAAAAAA
 8 => AAAAAAAA
 9 => AAAAAAAAA