2

私の仕事は、UIImage オブジェクトからすべての画像ピクセルを取得し、変数に格納することです。カラー画像でそれを行うのは難しくありません:

   CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);

    size_t ele = CGColorSpaceGetNumberOfComponents(colorSpace);

    CGFloat cols = image.size.width;
    CGFloat rows = image.size.height;

  // Create memory for the input image
    unsigned char *img_mem;
    img_mem = (unsigned char*) malloc(rows*cols*4);
    unsigned char *my_img;
    my_img = (unsigned char *)malloc(rows*cols*3);


    CGContextRef contextRef = CGBitmapContextCreate(img_mem,                                                                   cols,                       // Width of bitmap
                                                    rows,                       // Height of bitmap
                                                    8,                          // Bits per component
                                                    cols*4,              // Bytes per row
                                                    colorSpace,                 // Colorspace
                                                    kCGImageAlphaNoneSkipLast|kCGBitmapByteOrderDefault); // Bitmap info flags

    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);

    CGContextRelease(contextRef);
    CGColorSpaceRelease(colorSpace);

    unsigned int pos_new;
    unsigned int pos_old;
    for(int i=0; i<rows; i++)
    {
        pos_new = i*cols*3;
        pos_old = i*cols*4;

        for(int j=0; j<cols; j++)
        {
            my_img[j*3+pos_new] = img_mem[pos_old+j*4];
            my_img[j*3+pos_new+1] = img_mem[pos_old+j*4+1];
            my_img[j*3+pos_new+2] = img_mem[pos_old+j*4+2];

        }
    }

    free(img_mem);


 //All the pixels are installed in my_img

    free(my_img);

私の問題は、上記のコードがカラー画像に役立つことですが、グレースケール画像の場合はそれを行う方法がわかりません。何か案は?

4

2 に答える 2

2

問題は、入力および出力の画像形式に関する仮定を行うコードに数値がハードコーディングされていることです。このようにすることは、グレースケールのソース画像の正確な形式に完全に依存し、同様に、結果の画像をどの形式にするかにも依存します.

画像が常に 8 ビットのシングル チャネル グレースケールであることが確実な場合は、コード内の*4*3をすべて削除し、最後の内部ループを減らして 1 つのチャネルのみを処理するだけで済みます。

  for(int j=0; j<cols; j++)
  {
    my_img[j+pos_new] = img_mem[pos_old+j];
  }

ただし、出力イメージが 24 ビットになる場合 (コードが暗示しているように)、すべての出現を残す必要が*3あり、内側のループは次のようになります。

  for(int j=0; j<cols; j++)
    {
        my_img[j*3+pos_new] = img_mem[pos_old+j];
        my_img[j*3+pos_new+1] = img_mem[pos_old+j];
        my_img[j*3+pos_new+2] = img_mem[pos_old+j];

    }

これにより、24 ビットでグレースケール値が作成されます。

本当に柔軟にするには、colorSpace のコンポーネントを見て、それに基づいてピクセル処理ループを動的にコーディングするか、コードが期待する画像フォーマットでない場合は、少なくともある種の例外またはエラーをスローする必要があります。

于 2013-10-30T13:51:06.707 に答える
1

リンクのカテゴリ (UIImage+Pixels) を参照してください: http://b2cloud.com.au/tutorial/obtaining-pixel-data-from-a-uiimage

于 2013-10-30T13:31:10.777 に答える