3

そのため、最近はコアグラフィックのみを使用して多くの画像処理コードを記述しており、色を操作したり、ブレンドやブラーなどを適用したりする、かなりの数のフィルターを作成しました。しかし、次のような画像にポインティライズ効果を適用するためのフィルターを作成するのに問題があります。

ポインティライズ

私がやろうとしているのは、ピクセルの色を取得し、その色で楕円を塗りつぶし、画像をループして、ここで数ピクセルごとにこれを行うことです。コードは次のとおりです。

編集:これが今回の私の新しいコードです。画像の下部にいくつかの小さな円を描いているだけです。あなたが言ったように、私はそれを正しく行っていますか?

-(UIImage*)applyFilterWithAmount:(double)amount {

CGImageRef inImage = self.CGImage;
CFDataRef m_dataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage));
UInt8* m_pixelBuf = (UInt8*)CFDataGetBytePtr(m_dataRef);

int length = CFDataGetLength(m_dataRef);

CGContextRef ctx = CGBitmapContextCreate(m_pixelBuf,
                                    CGImageGetWidth(inImage),
                                    CGImageGetHeight(inImage),
                                    CGImageGetBitsPerComponent(inImage),
                                    CGImageGetBytesPerRow(inImage),
                                    CGImageGetColorSpace(inImage),
                                    CGImageGetBitmapInfo(inImage));

int row = 0;
int imageWidth = self.size.width;

if ((row%imageWidth)==0) {
    row++;
}

int col = row%imageWidth;

for (int i = 0; i<length; i+=4) {
    //filterPointillize(m_pixelBuf, i, context);

    int r = i;
    int g = i+1;
    int b = i+2;

    int red = m_pixelBuf[r];
    int green = m_pixelBuf[g];
    int blue = m_pixelBuf[b];

    CGContextSetRGBFillColor(ctx, red/255, green/255, blue/255, 1.0);
    CGContextFillEllipseInRect(ctx, CGRectMake(col, row, amount, amount));
}

CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
CGContextRelease(ctx);
UIImage* finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CFRelease(m_dataRef);
return finalImage;

}

4

1 に答える 1

1

すぐにわかる問題の 1 つは、X 原点と Y 原点の両方にラスター セル番号を使用していることです。この構成のラスターは、1 つのディメンション ラインにすぎません。ラスター イメージの幅に基づいて 2 番目の次元を計算するのは、ユーザー次第です。それはあなたがラインを得た理由を説明することができます.

別のこと: 画像のすべてのピクセルを読み取っているようです。描画しようとしている楕円の幅であるピクセルをスキップしたくありませんでしたか?

次に疑わしいと思われるのは、描画する前に、描画しているコンテキストを作成する必要があることです。さらに、次の呼び出しを行うべきではありません。

CGContextRef contextRef = UIGraphicsGetCurrentContext();
CGContextSaveGState(contextRef);

CGContextRestoreGState(contextRef);

ループ内。

編集:

もう 1 つの観察: 読み取った RGB 値は 0 ~ 255 であり、CGContextSetRGBFillColor関数は値が 0.f ~ 1.f の間であると想定しています。これで、白くなった理由が説明できます。したがって、255 で割る必要があります。

CGContextSetRGBFillColor(contextRef, red / 255, green / 255, blue / 255, 1.0);

他にご不明な点がございましたら、お気軽にお問い合わせください。

編集2:

行を計算するには、最初にループの外で行カウンターを宣言します。

int row = 0; //declare before the loop

int imageWidth = self.size.width; //get the image width

if ((i % imageWidth) == 0) { //we divide the cell number and if the remainder is 0
                             //then we want to increment the row counter
    row++;
}

mod を使用して現在の列を計算することもできます。

int col = i % imageWidth; //divide i by the image width. the remainder is the col num

編集 3:これを for ループ内に配置する必要があります。

if ((row%imageWidth)==0) {
    row++;
}

int col = row%imageWidth;

また、前に言及するのを忘れていましたが、列と行を 0 ベースにする (これが必要です) には、画像サイズから 1 を引く必要があります。

 int imageWidth = self.size.width - 1;
于 2012-08-05T21:24:30.707 に答える