数据压缩第九次作业:JPEG原理分析及JPEG解码器的调试
实验目的:
掌握JPEG编解码系统的基本原理。初步掌握复杂的数据压缩算法实现,并能根据理论分析需要实现所对应数据的输出。
主要设备:
安装Windows和Visual Studio软件的个人计算机
实验内容:
一、JPEG:
1.基本定义:
JPEG(Joint Photographic Experts Group)是JPEG标准的产物,该标准由国际标准化组织(ISO)制订,是面向连续色调静止图像的一种压缩标准。 [1] JPEG格式是最常用的图像文件格式,后缀名为.jpg或.jpeg。
2.JPEG编码基本原理:
如上图所示,JPEG的编码基本原理如上图所示:
(1)Level offset(零电平偏置):
将输入的图像的所有像素点的值-128,使其原先范围由0~255变为-128~127
(2)8✖️8DCT变换:
将零电平偏置之后的图像分成88像素的块来处理,不足88的,则取边缘像素补齐,对每个块做DCT变换,直流系数在每个块的左上角,越右下角的分量频率越高。
(3)Uniform scalar quantization(量化):
使用根据人眼视觉特性设计的量化的量化矩阵对DCT变换之后的结果进行量化,从而进而减少视觉冗余。
(4)DCT变换后DC系数值较大,且相邻块变化不大,利用这个特性对其进行DPCM,对相邻块的DC差值huffman编码
(5)对AC系数做之字形扫描,再进行游程编码和huffman编码
3.JPEG文件格式:
(1)Segment 的组织形式
JPEG 在文件中以 Segment 的形式组织,它具有以下特点:
(a)均以 0xFF 开始,后跟 1 byte 的 Marker 和 2 byte 的Segment length(包含表示 Length 本身所占用的 2 byte,不含“0xFF” + “Marker” 所占用的 2 byte);
(b) 采用 Motorola 序(相对于 Intel 序),即保存时高位在前,低位在后;
©Data 部分中,0xFF 后若为 0x00,则跳过此字节不予处理;
(2)JPEG的Segment Marker
(备注:此部分截图中的表格均为三列格式:分别为:“symbol(符号)”,“Code Assignment(0xFF+Marker)(标记代码)”,“Description(说明)”)
(a)Start Of Frame markers, non hierarchical Huffman coding
(b)Start Of Frame markers, hierarchical Huffman coding
©Start Of Frame markers, non-hierarchical arithmetic coding
(d)Start Of Frame markers, hierarchical arithmetic coding
(e)Huffman table specification
(f)arithmetic coding conditioning specification
(g)Restart interval termination
(h)Other marker
(i)Reserved markers
(3)部分Segment marker介绍:
(a)SOI:START OF IMAGE,图像开始,标记代码两字节,固定值0xFFD8
(b)EOI:END OF IMAGE,图像结束,标记代码两字节,固定值0xFFD9
(c)APP0应用程序保留标记0:
标记代码:2字节,固定值0xFFE0
(d)DQT定义量化表:标记代码2字节,固定值0xFFDB
包含9个具体字段:
数据长度:2字节,字段1和多个字段2的总长度
量化表:数据长度-2字节
a)精度及量化表ID:1字节
高4位:精度,只有两个可选值 0:8位,1:16位
b)表项:(64*(精度+1))字节
(e)SOF0:帧图像开始:标记代码2字节,固定值0xFFC0
包含9个具体字段:
数据长度:2字节,整个部分6个字段的总长度
精度:1字节,代表每个数据样本的位数,通常为8位
图像高度:2字节,单位像素
图像宽度:2字节,单位像素
颜色分量数:1字节,3个数值可选:
1:灰度图,3:YCrCb或者YIQ,4:CMYK
而JFIF中使用TCrCb,故这里颜色分量数恒为3
颜色分量信息:通常为9字节(颜色分量数✖️3字节)
ea)颜色分量ID,1字节
eb)水平/垂直采样因子,1字节,高4位:水平采样因子;第四位,垂直采样因子
ec)量化表,1字节,当前分量使用的量化表ID
(f)DHT:定义huffman表,标记代码2字节,0xFFC4
(g)SOS:扫描开始,标记代码2字节,固定值0xFFDA
3.JPEG解码基本原理
(1)读取文件
(2)解析segment marker
(a)解析 SOI
(b)解析 APP0
检查标识“JFIF”及版本并得到一些参数
© 解析 DQT
得到量化表长度(可能包含多张量化表)
得到量化表的精度
得到及检查量化表的序号(只能是 0 —— 3)
得到量化表内容(64 个数据)
(d)解析 SOF0
得到每个 sample 的比特数、长宽、颜色分量数
得到每个颜色分量的 ID、水平采样因子、垂直采样因子、使用的量化表 序号(与 DQT 中序号对应)
(e) 解析 DHT
得到 Huffman 表的类型(AC、DC)、序号
依据数据重建 Huffman 表 3.2.6 解析 SOS
得到解析每个颜色分量的 DC、AC 值所使用的 Huffman 表序号(与 DHT 中序号对应)
(3)依据每个分量的水平、垂直采样因子计算 MCU 的大小,并得到每个 MCU 中 8*8 宏块的个数
(4) 对每个 MCU 解码(依照各分量水平、垂直采样因子对 MCU 中每个分量宏块解 码)
(a)对每个宏块进行 Huffman 解码,得到 DCT 系数
(b)对每个宏块的 DCT 系数进行 IDCT,得到 Y、Cb、Cr
©遇到 Segment Marker RST 时,清空之前的 DC DCT 系数
(5)解析到 EOI,解码结束
(6) 将 Y、Cb、Cr 转化为需要的色彩空间并保存。
二、具体实验步骤
1.逐步调试JPEG解码器程序。将输入的JPG文件进行解码,将输出文件保存为可供YUVViewer观看的YUV文件。
在本次实验中,我们主要采用本图片,test.jpg进行操作:(嗯,看着有点晕其实)
首先在命令行中按照主程序中的设置添加参数,先运行一下代码:
而后我们便可以发现文件夹中生成了三个名为test的新文件,即:test.u,test.v,test.y,分别存储的是test.jpg图片转化为yuv文件之后的三个分量。
所以,我们需要对于原来的代码进行修改:
首先,我们找到write_yuv这个函数,从代码注释中,我们可以看出,这段就是使之输出test.u,test.v,test.y的相关代码:
所以,我们对本段代码进行如下添加,使之可以输出YUV文件:
static void write_yuv(const char *filename, int width, int height, unsigned char **components)
{FILE *F;char temp[1024];snprintf(temp, 1024, "%s.Y", filename);F = fopen(temp, "wb");fwrite(components[0], width, height, F);fclose(F);snprintf(temp, 1024, "%s.U", filename);F = fopen(temp, "wb");fwrite(components[1], width*height/4, 1, F);fclose(F);snprintf(temp, 1024, "%s.V", filename);F = fopen(temp, "wb");fwrite(components[2], width*height/4, 1, F);fclose(F);snprintf(temp, 1024, "%s.YUV", filename);F = fopen(temp, "wb");fwrite(components[0], width, height, F);fwrite(components[1], width * height / 4, 1, F);fwrite(components[2], width * height / 4, 1, F);fclose(F);
}
其中,需要注意的是,最开始输入命令行的时候可能出现报错:
“错误 D8016 “/ZI”和“/Gy-”命令行选项不兼容 ”
在查找了一下之后,发现需要做以下操作即可解决:
最后运行程序,可以看到,程序生成了一个test.yuv的文件,使用pyuv打开可以看到其和原图JPG形式的图片没有差别:
至此,本实验第一步完成。
2. 程序调试:
(1)程序运行的整体框架:(本部分的大部分介绍都以注释的形式,写在代码中)
首先介绍三个比较重要的结构体:
(a)struct huffman_table
struct huffman_table
{/* Fast look up table, using HUFFMAN_HASH_NBITS bits we can have directly the symbol,* if the symbol is <0, then we need to look into the tree table */short int lookup[HUFFMAN_HASH_SIZE];/* code size: give the number of bits of a symbol is encoded */unsigned char code_size[HUFFMAN_HASH_SIZE];/* some place to store value that is not encoded in the lookup table * FIXME: Calculate if 256 value is enough to store all values*/uint16_t slowtable[16-HUFFMAN_HASH_NBITS][256];
};
从这个结构体中,我们可以看出,其包含三个部分:其中lookup为short int型,用来加速查表,如果查找失败的话则就要使用慢速查找表。code_size为码字的长度。定义这个结构体的目的就是用来快速查找,从而加速程序的运行速度。
(b)struct component
struct component
{unsigned int Hfactor;unsigned int Vfactor;float *Q_table; /* Pointer to the quantisation table to use */struct huffman_table *AC_table;struct huffman_table *DC_table;short int previous_DC; /* Previous DC coefficient */short int DCT[64]; /* DCT coef */
#if SANITY_CHECKunsigned int cid;
#endif
};
这个结构体中,首先定义的Hfactor和Vfactor分别对应horizontal和vertical即水平和垂直方向的采样信息。而后定义Q_table则是对应此次DCT变换所对应的量化表,DCT[64]则代表这个8✖️8的宏块所存储的DCT系数,previousDC则指的是前一个直流系数。
这部分的主要用途就是用来存储每一个MCU的信息,用来进行DCT的变换。
(c)struct jdec_private
struct jdec_private
{/* Public variables */uint8_t *components[COMPONENTS];unsigned int width, height; /* Size of the image */unsigned int flags;/* Private variables */const unsigned char *stream_begin, *stream_end;unsigned int stream_length;const unsigned char *stream; /* Pointer to the current stream */unsigned int reservoir, nbits_in_reservoir;struct component component_infos[COMPONENTS];float Q_tables[COMPONENTS][64]; /* quantization tables */struct huffman_table HTDC[HUFFMAN_TABLES]; /* DC huffman tables */struct huffman_table HTAC[HUFFMAN_TABLES]; /* AC huffman tables */int default_huffman_table_initialized;int restart_interval;int restarts_to_go; /* MCUs left in this restart interval */int last_rst_marker_seen; /* Rst marker is incremented each time *//* Temp space used after the IDCT to store each components */uint8_t Y[64*4], Cr[64], Cb[64];jmp_buf jump_state;/* Internal Pointer use for colorspace conversion, do not modify it !!! */uint8_t *plane[COMPONENTS];};
此部分的结构体则是包含整合了以上两个结构体中的内容,在解码过程中,我们会频繁使用到这个结构体。在这个结构体中,其保存了图像的所有基本信息,在解码完成之后,该结构体存储JPEG文件中的具体信息。
而后我们再从主程序最开头开始理解程序的框架:
int main(int argc, char *argv[])
{int output_format = TINYJPEG_FMT_YUV420P;//将输出格式初始化为yuv420格式char *output_filename, *input_filename;//定义两个指针,用来输入输出文件clock_t start_time, finish_time;unsigned int duration;int current_argument;//定义变量用来选取命令参数int benchmark_mode = 0;
#if TRACE//在头文件中,已经定义了TRACE的初始化值为1,如果TRACE不为1,则这步不会调用p_trace=fopen(TRACEFILE,"w");if (p_trace==NULL){printf("trace file open error!");}
#endifif (argc < 3)usage();current_argument = 1;while (1){if (strcmp(argv[current_argument], "--benchmark")==0)benchmark_mode = 1;elsebreak;current_argument++;}if (argc < current_argument+2)usage();input_filename = argv[current_argument];//指向输入文件的文件路径if (strcmp(argv[current_argument+1],"yuv420p")==0)output_format = TINYJPEG_FMT_YUV420P;//指向命令参数的第二个,确认文件的输出格式else if (strcmp(argv[current_argument+1],"rgb24")==0)output_format = TINYJPEG_FMT_RGB24;else if (strcmp(argv[current_argument+1],"bgr24")==0)output_format = TINYJPEG_FMT_BGR24;else if (strcmp(argv[current_argument+1],"grey")==0)output_format = TINYJPEG_FMT_GREY;elseexitmessage("Bad format: need to be one of yuv420p, rgb24, bgr24, grey\n");//如果输入的格式这上面的格式都没有//那么这个程序就不能正常生效,也就是会显示这条提示output_filename = argv[current_argument+2];//指向命令参数的第三个,确认文件的输出路径start_time = clock();if (benchmark_mode)load_multiple_times(input_filename, output_filename, output_format);elseconvert_one_image(input_filename, output_filename, output_format);finish_time = clock();duration = finish_time - start_time;snprintf(error_string, sizeof(error_string),"Decoding finished in %u ticks\n", duration);
#if TRACEfclose(p_trace);
#endifreturn 0;
}
从主程序中,我们主要需要知道的是,整个解码器程序可以将JPEG文件转化为很多种其他格式的文件,而其解码的过程则是主要调用了convert_one_image这个函数,当然,也可以是调用load_mutiple_times这个函数,通过benchmatk_mode这个变量来进行选择,在本实验的运行中,我们会调用的是convert_one_image这个函数:
/*** Load one jpeg image, and decompress it, and save the result.*/
int convert_one_image(const char *infilename, const char *outfilename, int output_format)
{FILE *fp;//定义文件指针fpunsigned int length_of_file;//定义变量用以保存读入文件的大小unsigned int width, height;//定义图像的长宽unsigned char *buf;//定义缓冲区struct jdec_private *jdec;unsigned char *components[3];/* Load the Jpeg into memory */fp = fopen(infilename, "rb");//读取JPEG文件if (fp == NULL)exitmessage("Cannot open filename\n");length_of_file = filesize(fp);//保存读入文件的大小buf = (unsigned char *)malloc(length_of_file + 4);if (buf == NULL)exitmessage("Not enough memory for loading file\n");fread(buf, length_of_file, 1, fp); //将JPEG数据读入bufferfclose(fp);/* Decompress it */jdec = tinyjpeg_init();//初始化解压缩成一块表和数组的结构体if (jdec == NULL)exitmessage("Not enough memory to alloc the structure need for decompressing\n");if (tinyjpeg_parse_header(jdec, buf, length_of_file)<0)exitmessage(tinyjpeg_get_errorstring(jdec));/* Get the size of the image */tinyjpeg_get_size(jdec, &width, &height);snprintf(error_string, sizeof(error_string),"Decoding JPEG image...\n");if (tinyjpeg_decode(jdec, output_format) < 0)exitmessage(tinyjpeg_get_errorstring(jdec));/* * Get address for each plane (not only max 3 planes is supported), and* depending of the output mode, only some components will be filled * RGB: 1 plane, YUV420P: 3 planes, GREY: 1 plane*/tinyjpeg_get_components(jdec, components);/* Save it */switch (output_format)//进行格式判断,用以调用相应的函数,从而按要求输出文件{case TINYJPEG_FMT_RGB24:case TINYJPEG_FMT_BGR24:write_tga(outfilename, output_format, width, height, components);break;case TINYJPEG_FMT_YUV420P:write_yuv(outfilename, width, height, components);break;case TINYJPEG_FMT_GREY:write_pgm(outfilename, width, height, components);break;}/* Only called this if the buffers were allocated by tinyjpeg_decode() */tinyjpeg_free(jdec);/* else called just free(jdec); */free(buf);return 0;
}
convert_one_image的主要作用是读取我们所输入的JPEG文件,并对其进行解压缩。其中我们首先用到了tinyjpeg_parse_header这个函数用来解析文件头:
int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size)
{int ret;/* Identify the file */if ((buf[0] != 0xFF) || (buf[1] != SOI))snprintf(error_string, sizeof(error_string),"Not a JPG file ?\n");priv->stream_begin = buf+2;priv->stream_length = size-2;priv->stream_end = priv->stream_begin + priv->stream_length;ret = parse_JFIF(priv, priv->stream_begin);return ret;
}
而后,我们也用到了tinyjpeg_get_siz函数来获取图像大小和长宽:
void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height)
{*width = priv->width;*height = priv->height;
}
再然后又用到了tinyjpeg_decode用来解码:
int tinyjpeg_decode(struct jdec_private *priv, int pixfmt)
{unsigned int x, y, xstride_by_mcu, ystride_by_mcu;unsigned int bytes_per_blocklines[3], bytes_per_mcu[3];decode_MCU_fct decode_MCU;const decode_MCU_fct *decode_mcu_table;const convert_colorspace_fct *colorspace_array_conv;convert_colorspace_fct convert_to_pixfmt;if (setjmp(priv->jump_state))return -1;/* To keep gcc happy initialize some array */bytes_per_mcu[1] = 0;bytes_per_mcu[2] = 0;bytes_per_blocklines[1] = 0;bytes_per_blocklines[2] = 0;decode_mcu_table = decode_mcu_3comp_table;switch (pixfmt) {case TINYJPEG_FMT_YUV420P:colorspace_array_conv = convert_colorspace_yuv420p;if (priv->components[0] == NULL)priv->components[0] = (uint8_t *)malloc(priv->width * priv->height);if (priv->components[1] == NULL)priv->components[1] = (uint8_t *)malloc(priv->width * priv->height/4);if (priv->components[2] == NULL)priv->components[2] = (uint8_t *)malloc(priv->width * priv->height/4);bytes_per_blocklines[0] = priv->width;bytes_per_blocklines[1] = priv->width/4;bytes_per_blocklines[2] = priv->width/4;bytes_per_mcu[0] = 8;bytes_per_mcu[1] = 4;bytes_per_mcu[2] = 4;break;case TINYJPEG_FMT_RGB24:colorspace_array_conv = convert_colorspace_rgb24;if (priv->components[0] == NULL)priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3);bytes_per_blocklines[0] = priv->width * 3;bytes_per_mcu[0] = 3*8;break;case TINYJPEG_FMT_BGR24:colorspace_array_conv = convert_colorspace_bgr24;if (priv->components[0] == NULL)priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3);bytes_per_blocklines[0] = priv->width * 3;bytes_per_mcu[0] = 3*8;break;case TINYJPEG_FMT_GREY:decode_mcu_table = decode_mcu_1comp_table;colorspace_array_conv = convert_colorspace_grey;if (priv->components[0] == NULL)priv->components[0] = (uint8_t *)malloc(priv->width * priv->height);bytes_per_blocklines[0] = priv->width;bytes_per_mcu[0] = 8;break;default:
#if TRACEfprintf(p_trace,"Bad pixel format\n");fflush(p_trace);
#endifreturn -1;}
同时也调用了tinyjpeg_get_components:
int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components)
{int i;for (i=0; priv->components[i] && i<COMPONENTS; i++)components[i] = priv->components[i];return 0;
}
最后又会调用write_yuv函数,用来将转化完成的yuv文件写出(本函数已经根据实验要求完成了修改):
static void write_yuv(const char *filename, int width, int height, unsigned char **components)
{FILE *F;char temp[1024];snprintf(temp, 1024, "%s.Y", filename);F = fopen(temp, "wb");fwrite(components[0], width, height, F);fclose(F);snprintf(temp, 1024, "%s.U", filename);F = fopen(temp, "wb");fwrite(components[1], width*height/4, 1, F);fclose(F);snprintf(temp, 1024, "%s.V", filename);F = fopen(temp, "wb");fwrite(components[2], width*height/4, 1, F);fclose(F);snprintf(temp, 1024, "%s.YUV", filename);F = fopen(temp, "wb");fwrite(components[0], width, height, F);fwrite(components[1], width * height / 4, 1, F);fwrite(components[2], width * height / 4, 1, F);fclose(F);
}
(3)Trace的目的及含义:
TRACE随着文件的解析,也会一直输出中间信息,在使用过程中,我们初始状态设置了:
#define TRACE 1//add by nxn
也就是说,只要TRACE的值为1,那么就代表TRACE被打开,可以用来记录程序运行过程中的重要中间信息。
例如利用TRACE的一个例子如下:
#if TRACE//在头文件中,已经定义了TRACE的初始化值为1,如果TRACE不为1,则这步不会调用p_trace=fopen(TRACEFILE,"w");if (p_trace==NULL){printf("trace file open error!");}
#endif
根据自己的要求修改TRACE:
首先,正常情况下,TRACE的内容会生成到文件夹中的trace_jpeg.txt中:
此时,生成SOF marker处的代码为:
#if TRACEfprintf(p_trace,"> SOF marker\n");fprintf(p_trace,"Size:%dx%d nr_components:%d (%s) precision:%d\n", width, height,nr_components, nr_components_to_string[nr_components],precision);fflush(p_trace);
#endif
之后,我们删除了写出precision的部分,代码如下:
#if TRACEfprintf(p_trace,"> SOF marker\n");fprintf(p_trace,"Size:%dx%d nr_components:%d (%s)\n", width, height,nr_components, nr_components_to_string[nr_components]);fflush(p_trace);
#endif
}
输出结果如下,可见已经完成了TRACE的调试操作:
3.以txt文件输出所有的量化矩阵和所有的HUFFMAN码表。
首先:在头文件tinyjpeg.h中添加下列代码:
FILE *p_trace;//add by nxn
FILE* huffmantable;//新建一个文件指针,并利用它来生成一个txt,用来存放输出的huffman码表
FILE* DC;//新建一个文件指针,并利用它来生成一个yuv,用来存放输出的DC图像
FILE* AC;//新建一个文件指针,并利用它来生成一个yuv,用来存放输出的AC图像
FILE* quantization;//新建一个文件指针,并利用它来生成一个txt,用来存放输出的量化矩阵
而后在主函数中的trace部分添加如下代码:
if TRACE//在头文件中,已经定义了TRACE的初始化值为1,如果TRACE不为1,则这步不会调用p_trace=fopen(TRACEFILE,"w");if (p_trace==NULL){printf("trace file open error!\n");}if ((fopen_s(&huffmantable, "huffmantable.txt", "ab")) != 0){printf("Failed to open the txt file.\n");}else{printf("Successfully opened the txt file.\n");}if ((fopen_s(&DC, "DC.yuv", "ab")) != 0){printf("Failed to open the yuv file.\n");}else{printf("Successfully opened the yuv file.\n");}if ((fopen_s(&AC, "AC.yuv", "ab")) != 0){printf("Failed to open the yuv file.\n");}else{printf("Successfully opened the yuv file.\n");}if ((fopen_s(&quantization, "quantization.txt", "ab")) != 0){printf("Failed to open the txt file.\n");}else{printf("Successfully opened the txt file.\n");}#endif
而后在build_huffman_table的trace中添加:
#if TRACEfprintf(p_trace,"val=%2.2x code=%8.8x codesize=%2.2d\n", val, code, code_size);fprintf(huffmantable, "val=%2.2x code=%8.8x codesize=%2.2d\n", val, code, code_size);//添加fflush(p_trace);#endif
最后在parse_DHT的trace中添加:
if TRACEfprintf(p_trace,"Huffman table %s[%d] length=%d\n", (index&0xf0)?"AC":"DC", index&0xf, count);fprintf(huffmantable, "Huffman table %s[%d] length=%d\n", (index & 0xf0) ? "AC" : "DC", index & 0xf, count);//添加fflush(p_trace);
#endif
最后运行程序,可以看见文件夹中输出了一个huffmantable.txt的文件,打开后内容如下:
对于量化表方面,则是要首先对parse_DQT函数中的这部分进行添加
#if SANITY_CHECKif (qi >> 4)snprintf(error_string, sizeof(error_string), "16 bits quantization table is not supported\n");if (qi > 4)snprintf(error_string, sizeof(error_string), "No more 4 quantization table is supported (got %d)\n", qi);
#endif
#if TRACEfprintf(quantization, "Quantization_table [%d]:\n", qi);fflush(quantization);
#endiftable = priv->Q_tables[qi];build_quantization_table(table, stream);stream += 64;}
而后,再对函数build_quantization_table进行添加:
static void build_quantization_table(float *qtable, const unsigned char *ref_table)
{/* Taken from libjpeg. Copyright Independent JPEG Group's LLM idct.* For float AA&N IDCT method, divisors are equal to quantization* coefficients scaled by scalefactor[row]*scalefactor[col], where* scalefactor[0] = 1* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7* We apply a further scale factor of 8.* What's actually stored is 1/divisor so that the inner loop can* use a multiplication rather than a division.*/int i, j;static const double aanscalefactor[8] = {1.0, 1.387039845, 1.306562965, 1.175875602,1.0, 0.785694958, 0.541196100, 0.275899379};const unsigned char *zz = zigzag;for (i=0; i<8; i++) {for (j=0; j<8; j++) {
#if TRACEfprintf(quantization, "%d\t", ref_table[*zz]);//输出量化表fflush(quantization);if (j == 7){fprintf(quantization, "\n");//每八个换一次行(8*8矩阵)fflush(quantization);}
#endif*qtable++ = ref_table[*zz++] * aanscalefactor[i] * aanscalefactor[j];}}}
运行程序之后,可以发现文件夹中生成了一个名为quantizaiton的txt文件,打开后结果如下:
4&5. 输出DC图像并统计其概率分布,输出某一个AC值图像并统计其概率分布。
在这一步中,我们需要对tinyjpeg_decode函数中的for循环部分添加如下代码用来输出其DC图像和AC图像:
unsigned char* DC_BUFFER = NULL;unsigned char* AC_BUFFER = NULL;DC_BUFFER = (unsigned char)((priv->component_infos->DCT[0] + 512.0) / 4 + 0.5);AC_BUFFER = (unsigned char)(priv->component_infos->DCT[1] + 128);fwrite(&DC_BUFFER, 1, 1, DC);fwrite(&AC_BUFFER, 1, 1, AC);
运行程序,我们可以得到两个名字为AC和DC的YUV文件,使用PYUV软件打开并将其转化为bmp文件之后,我们可以得到DC图像和AC图像:
DC图像:
AC图像:
其中,此时输出的DC图像和AC图像的尺寸均为128128,因为原本的图像为10241024,1024/8之后得出的尺寸即为新图像的长宽。
最后,我们调用之前写好的计算概率分布和熵的函数,即可统计其概率分布:
#include<iostream>
#include<math.h>
using namespace std;
#define w 128
#define h 128
int main()
{FILE* YUV = NULL;FILE* OUTPUT = NULL;if ((fopen_s(&YUV, "AC.yuv", "rb")) != 0){cout << "Failed to open the YUV file!" << endl;}else{cout << "File successfully opened!" << endl;}if ((fopen_s(&OUTPUT, "AC.txt", "wb")) != 0){cout << "Failed to open the txt file!" << endl;}else{cout << "File successfully opened!" << endl;}unsigned char* YUV_BUFFER = NULL;YUV_BUFFER = new unsigned char[w*h];fread(YUV_BUFFER, sizeof(unsigned char), w*h, YUV);double Frequency[256] = { 0 };int calculate[256] = { 0 };double Entropy = 0;for (int i = 0; i < 256; i++){for (int j = 0; j < w * h; j++){if (i == int(YUV_BUFFER[j])){calculate[i]++;}}}for (int i = 0; i < 256; i++){Frequency[i] = (double)calculate[i] / w / h;if (Frequency[i] != 0){Entropy += (-1) * Frequency[i] * (log(Frequency[i]) / log(2));}}fprintf(OUTPUT, "symbol\tfrequency\n");for (int i = 0; i < 256; i++){fprintf(OUTPUT, "%d\t%f\n", i, Frequency[i]);}cout << "The Entorpy of is:" << Entropy << endl;}
DC概率分布:
AC概率分布:
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- JLing家庭管家(基于Agora技术实现)
JLing JLing是一个可以工作在Linux的自定义中文语音对话机器人 (csdn :https://blog.csdn.net/weixin_40490238) (github: https://github.com/Kingzhoudk/JLing) 基于Agora技术对JLing的改造,成功实现了视频聊天、智能家居的远程控制、监控等功能。 视频链接: bilibili 整体…...
2024/5/9 0:13:12 - Spring + Hibernate多租户配置
介绍 多租户(Multi-tenancy)是一种软件架构,一个服务实例可以服务多个客户,每个客户叫一个租户。而这其中最关键的一部分就是各个租户的数据的分离。 针对这种情形,主要有三种策略,数据的隔离级别从高到低依次是:Database per Tenant, Shared Database, Separate Schema, …...
2024/4/24 8:11:53 - 玩转Docker----- 第三部-----------docker公有、私有仓库的搭建
玩转Docker----- 第三部-----------docker公有、私有仓库的搭建 1.Docker 仓库 Docker仓库是用来包含镜像的位置,Docker提供一个注册服务器 (Register)来保存多个仓库,每个仓库又可以包含多个具备不同tag的镜像。 Docker运行中使用的默认仓库是Docker Hub公共仓库。 仓库的出…...
2024/4/24 8:11:59 - ES6标准入门
文章目录一、什么是ES6?二、为什么使用ES6?三、ES6语法特性3.1 新的声明方法3.2 let 命令3.3 const 命令四、 解构赋值4.1 数组模型的解构(Array)4.1.1 基本4.1.2 可嵌套4.1.3 可忽略4.1.4 不完全解构4.1.5 剩余运算符4.1.6 字符串等4.2 对象模型的解构(Object)4.2.1 基…...
2024/5/8 15:36:42 - Python基础语法_小结
Python基础语法_小结1 Python语言介绍&安装配置1.1 Python数据相关应用1.2 Python特点1.3 生成配置文件,修改默认路径2 Python基础语法2.1 关键字(即保留字)2.2 输入和输出2.3 声明变量2.4 自增运算3 标准数据类型3.1 布尔值bool3.1.1 布尔值的运算符3.2 数字numbers…...
2024/4/20 9:53:20 - python零基础学习之os模块的学习
OS模块的学习 1.os.name 如果结果为nt, 则为windows系统, 如果结果为posix, 则为unix系统 当存在跨系统的时候则可以用这个做一个判断比如: if os.name == "nt":cmd = "ipconfig" elif os.name == "posix": cmd = "ifconfig"os.sy…...
2024/4/16 16:27:38 - Java编程思想 第四版全部习题答案
http://greggordon.org/java/tij4/solutions.htm...
2024/5/3 20:47:13 - LeetCode-1132. 报告的记录 II (中等)
题目来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/reported-posts-ii 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 本人思路: 1、将actions表与removals表根据条件a.post_id = r.post_id左连接 ,并且筛选出 extra = spam’行 …...
2024/5/3 15:15:15 - java—单例模式实现方式
1.饿汉式(线程安全,调用效率高,但是不能延时加载):JVM初始化的时候创建对象,不能延时public class ImageLoader{ private static ImageLoader instance = new ImageLoader; private ImageLoader(){} public static ImageLoader getInstance(){ return instance; } }2.懒…...
2024/4/16 16:27:48 - java学习基础知识之认识-静态修饰符static
1:静态修饰符static 可修饰1.变量—2.方法–3.代码块! —————————————————————————————————— a:修饰变量:静态变量! —————————————————————————————————— class B{ //int i=1; 此处i位成员变量:属…...
2024/5/3 12:32:59 - GD32F407之硬件IIC(从机模式)
承接上一篇GD32F407硬件IIC主机模式,下面这一片介绍GD32F407硬件IIC从机模式,用MCU来做从机模式百度上有用的资源比较少,都是STM32里面的源码,千篇一律,有点水帖的感觉。网上百度用GPIO模拟方式来做从机好像没有找到资料,也咨询了GD32F407的FE没有做过GPIO模拟从机,所以…...
2024/4/15 6:53:31 - Linux chgrp 命令
命令详解 Linux chgrp命令用于变更文件或目录的所属群组。 在UNIX系统家族里,文件或目录权限的掌控以拥有者及所属群组来管理。您可以使用chgrp指令去变更文件与目录的所属群组,设置方式采用群组名称或群组识别码皆可。 命令全拼 chgrp = change group 语法格式chgrp [-cfhRv…...
2024/4/18 13:47:49 - HiveSQL优化技巧
技巧1:用group by替换distinct。 原有写法: SELECT distinct user_name FROM user_trade WHERE dt>0;优化写法: SELECT user_name FROM user_trade WHERE dt>0 GROUP BY user_name;使用group by可以看到运行时间减少许多。 注意:在极大的数据量(较多重复值)时,可以…...
2024/4/24 8:11:50 - 街景编码字符识别系列(三)
街景编码字符识别系列(三)1.CNN介绍2.CNN发展 1.CNN介绍 卷积神经网络(简称CNN)是一类特殊的人工神经网络,是深度学习中重要的一个分支。CNN在很多领域都表现优异,精度和速度比传统计算学习算法高很多。特别是在计算机视觉领域,CNN是解决图像分类、图像检索、物体检测和…...
2024/5/3 12:01:52 - TCP协议
TCP协议解读 一、TCP头部解析:0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Source Port | …...
2024/4/24 8:11:50 - MQ2和MQ7电压值与PPM的转换公式
最近给人做了个机智云的环境监测程序,第一次赚外快,100块钱我就接了。写程序的时候发现好多人在找这两传感器电压值和PPM的转换,我这个也是照搬别人的公式,不过效果还不错。不过遗憾的是,我都写的差不多了,他又要让我换ONENET,ONENET我不太熟,他就又给了我100让我帮他搞…...
2024/4/29 14:44:23 - 如果类A和类B是从同一个基类N派生的,且类D是类A和类B的多重继承派生类,要求在程序中通过类A和类B的构造函数去调用基类N的构造函数,分别对类A和类B的数据成员a初始化。
如果类A和类B是从同一个基类N派生的,且类D是类A和类B的多重继承派生类,要求在程序中通过类A和类B的构造函数去调用基类N的构造函数,分别对类A和类B的数据成员a初始化。 #include<iostream> using namespace std;class N {public:N(int aN){a=aN;}int a;void display()…...
2024/5/1 1:48:13 - 二、java万物皆可盘之用引用操纵对象
用引用操纵对象 雷迪森and砖头们,让我们来说下引用和对象有啥区别? 在前面的文章中简单概括了对象(某个将数据和功能封装到一块的实例),下面我们举个简单的例子:把“人”作为一个类型,实例化出一个具体的名叫李小明的人,这个人是一个对象。引用就是给这个实例化出的人起…...
2024/4/24 8:11:52 - Win10中安装Docker并运行Windows Server Core2019
1、官网下载并安装,非常easy https://store.docker.com/editions/community/docker-ce-desktop-windows2、建议使用阿里的“镜像加速器”服务,否则会比较慢,找到加速器地址3、打开docker程序,将地址配置到中红框位置,并点击“Apply & Restart”4、在cmd中执行如下命令…...
2024/4/24 8:11:53 - 【博客263】C++:请勿修改set的键
内容: 记录修改C++的set的键会引发编译错误 代码: #include<set> #include <iostream> using namespace std;int main() {set<int> test; test.insert(1);test.insert(2);test.insert(3);test.insert(4); auto it = test.begin();*it = 10…...
2024/5/6 0:24:14
最新文章
- 探索Java的未来
探索 Java 的未来是一个非常有趣的话题。Java 是一种广泛使用的编程语言,自 1995 年诞生以来,它已经在软件开发领域占据了重要的地位。尽管有些人担心 Java 可能会因为新技术的出现而变得不再相关,但实际情况并非如此。让我们来看看一些关于 …...
2024/5/9 1:14:31 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/5/7 10:36:02 - 怎么保证缓存与数据库的最终一致性?
目录 零.读数据的标准操作 一.Cache aside Patten--旁路模式 二.Read/Write Through Pattern--读写穿透 三.Write Back Pattern--写回 四.运用canal监听mysql的binlog实现缓存同步 零.读数据的标准操作 这里想说的是不管哪种模式读操作都是一样的,这是一种统一…...
2024/5/2 16:12:59 - Python语法总结:not(常出现错误)
0、not是什么 在python中not是逻辑判断词,用于布尔型True和False之前 a not Ture # a False b not False # b True1、not的用法 (1)判断语句 if not a:# 如果a是False,执行的语句(2)判断元素是否在…...
2024/5/7 15:29:37 - Windows 2008虚拟机安装、安装VM Tools、快照和链接克隆、添加硬盘修改格式为GPT
一、安装vmware workstation软件 VMware workstation的安装介质,获取路径: 链接:https://pan.baidu.com/s/1AUAw_--yjZAUPbsR7StOJQ 提取码:umz1 所在目录:\vmware\VMware workstation 15.1.0 1.找到百度网盘中vmwa…...
2024/5/8 18:45:14 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/8 6:01:22 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/5/7 9:45:25 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/5/4 23:54:56 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/7 14:25:14 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/5/4 23:54:56 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/5/4 23:55:05 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/5/4 23:54:56 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/5/7 11:36:39 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/5/4 23:54:56 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/5/6 1:40:42 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/5/4 23:54:56 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/5/8 20:48:49 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/5/7 9:26:26 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/5/4 23:54:56 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/8 19:33:07 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/5/5 8:13:33 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/5/8 20:38:49 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/5/4 23:54:58 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/6 21:42:42 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/5/4 23:54:56 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57