1

JPEG画像をiOSフォトライブラリに保存するときに奇妙な変更があります。何か間違ったことをしているのかわかりません。libjpeg-turboを使用してJPEG画像にアクセスしてから、画像のDCT係数を変更しています。変更された画像(DCTだけで、他には何もありません)はフォトライブラリに保存されます。しかし、保存した画像を開いた後、DCT係数は前の手順で変更したものと同じではありません。

詳細に、各DCTに+1を追加する方法を説明します。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係数が変更されたままであることを確認しました。修正離散コサイン変換で同じ画像をチェックしたら、それを保存します。

UIImageWriteToSavedPhotosAlbum(imageToSave, nil, nil, nil);

画像「new.jpg」がフォトライブラリに保存されました。

これまでは、すべてがうまく機能し、DCT係数はlibjpegライブラリで意図されていたように機能します。保存した画像を再度ロードしてDCT係数を調べると、変更が発生します。DCTが変更されていることがわかりましたが、その理由はわかりません。JPEG画像を保存するときにiOSが使用する最適化アルゴリズムはありますか?DCTが変更されるのはなぜですか。

保存した画像を読み取るために、次の手順を使用しています。

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を変更し、1つの8x8ブロックのフォトライブラリに保存した後に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 

どんな助けでもいただければ幸いです。画像をフォトライブラリに保存した後のDCTが変更されたのはなぜですか。

4

2 に答える 2

2

UIImage とそのメソッドを使用すると、iOS は常に JPEG を再圧縮するため、DCT が変更されます。代わりに、AssetsLibrary を使用して、ユーザーの写真を NSData として保存および取得します。この動作は文書化されていませんが、機能します。

.jpeg を一時フォルダーに保存してから、libjpeg-turbo にフィードすることもお勧めします。

于 2012-12-26T23:41:42.140 に答える