DCT系数改变后JPEG保存到iOS照片库

问题描述 投票:1回答:2

有保存JPEG图像iOS的照片库时,一个奇怪的变化。我不知道我做错了什么。我使用的libjpeg涡轮访问JPEG图像,然后我修改图像的DCT系数。修改后的图像(只是在DCT,没有别的)保存在照片库中。但之后,我打开保存的图像,DCT系数是不是我在前面的步骤改变一样。

具体而言,让我解释一下我如何添加+1到每个DCT。我使用从libjpeg的图书馆“example.c”标准程序:

struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
FILE * infile;

if ((infile = fopen(filename, "rb")) == NULL) {
    fprintf(stderr, "can't open %s\n", filename);
    return 0;
}

cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;

if (setjmp(jerr.setjmp_buffer)) {
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);
    return 0;
}

jpeg_create_decompress(&cinfo);

jpeg_stdio_src(&cinfo, infile);

(void) jpeg_read_header(&cinfo, TRUE);

jvirt_barray_ptr* coeffs_array;
coeffs_array = jpeg_read_coefficients(&cinfo);

BOOL done = FALSE;
for (int ci = 0; ci < 3; ci++)
{
    JBLOCKARRAY buffer_one;
    JCOEFPTR blockptr_one;
    jpeg_component_info* compptr_one;
    compptr_one = cinfo.comp_info + ci;

    for (int by = 0; by < compptr_one->height_in_blocks; by++)
    {
        buffer_one = (cinfo.mem->access_virt_barray)((j_common_ptr)&cinfo, coeffs_array[ci], by, (JDIMENSION)1, FALSE);

        for (int bx = 0; bx < compptr_one->width_in_blocks; bx++)
        {
            blockptr_one = buffer_one[0][bx];

            for (int bi = 0; bi < 64; bi++)
            {
                blockptr_one[bi]++;
            }                  
        }   
    } 
}

write_jpeg(output, &cinfo, coeffs_array); // saving modified JPEG to the output file

jpeg_destroy_decompress(&cinfo);
fclose(infile);

在此之后我保存在文件中新的JPEG图像,让我们说“new.jpg”。现在,我要救这个“new.jpg”的照片库,所以我通过加载图像:

imageToSave = [UIImage imageWithContentsOfFile:outputFile];

我还检查了DCT系数仍然改变。我有经过相同的图像wuth我修改DCT选中,那么我要保存它:

UIImageWriteToSavedPhotosAlbum(imageToSave, nil, nil, nil);

图像“new.jpg”现在保存在照片库中。

到现在为止,一切都很正常,DCT系数如同它被用的libjpeg库的意思。这种变化是当我再次加载保存的图像,并期待为DCT系数。我发现,双离合变速器的改变,我不知道为什么。是否有当要保存的JPEG图像,内部监督办公室使用任何优化算法?为什么双离合变速器改变。

我使用下面的方法来读取保存的图像:

NSData *jpegData = UIImageJPEGRepresentation([info objectForKey:UIImagePickerControllerOriginalImage], 1);
[jpegData writeToFile:file atomically:YES]; // saved image is saved in file and I can use the procedure from above to check DCTs

另外,这是原始的DCT的一个例子,通过添加1到所有修改的DCT,并将其保存到照片库,用于一个8×8块后的DCT加载:

Original DCTs:
-759 -24 -8 1 -1 0 0 1 
56 -27 -10 1 0 1 0 0 
8 0 0 0 0 -1 0 0 
0 0 0 -1 0 -1 0 -1 
0 0 0 1 0 0 0 0 
0 0 0 1 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 -1 0 0 0 0 

Modified DCTs by libjpeg:
-758 -23 -7 2 0 1 1 2 
57 -26 -9 2 1 2 1 1 
9 1 1 1 1 0 1 1 
1 1 1 0 1 0 1 0 
1 1 1 2 1 1 1 1 
1 1 1 2 1 1 1 1 
1 1 1 1 1 1 1 1 
1 1 1 0 1 1 1 1 

DCTs after saving JPEG to photo library:
-758 -22 -7 2 0 0 0 0 
58 -26 -8 3 0 0 0 0 
8 2 0 0 -1 1 0 0 
2 3 0 0 0 0 0 0 
2 1 -1 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 -1 

任何帮助,将不胜感激。我真的出了,为什么保存图像,以改变照片库后双离合变速器的想法。

ios jpeg libjpeg dct
2个回答
2
投票

当您使用的UIImage及其方法,从而改变DCT的iOS将始终重新压缩您的JPEG。相反,使用AssetsLibrary来存储和检索用户的图片作为NSData的。这种行为是没有记录,但它的作品。

我也建议存储JPEG格式的临时文件夹,然后喂养它的libjpeg到涡轮增压。


-1
投票

你应该明确地简化代码,看看那里发生意外行为。你这样做至少有五种不同的步骤,其中事情都可能出错。

现在,有人说,没有工作在iOS但我们知道JPEG编解码器,小心你用来保存你的file.jpg质量。我不知道什么是您的特定库的默认,但如果不是100%,这将决定性地影响你的DCT系数。

尝试使用无损编解码器,如PNG或BMP保存修改后的图像。

© www.soinside.com 2019 - 2024. All rights reserved.