iOS:在uiimage上使用发光/阴影效果的羽毛

时间:2014-02-20 06:31:19

标签: ios objective-c uiimage core-graphics shadow

我试图找到一种方法来应用羽毛效果和UIImage周围的阴影,而不是我在iOS中的UIImageView,我找不到任何完美的解决方案。我知道它可以通过屏蔽来完成,但我对CoreGraphics非常新。

如果有人可以提供帮助。

感谢。

2 个答案:

答案 0 :(得分:4)

好的:   我一直在寻找相同的东西,但遗憾的是没有运气。 我决定创建自己的羽毛代码。

将此代码添加到UIImage扩展程序,然后调用[image featherImageWithDepth:4],4就是示例。 尽量保持尽可能低的深度。

//==============================================================================


- (UIImage*)featherImageWithDepth:(int)featherDepth {

    // First get the image into your data buffer
    CGImageRef imageRef = [self CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);


    // Now your rawData contains the image data in the RGBA8888 pixel format.
    NSUInteger byteIndex = 0;



    NSUInteger rawDataCount = width*height;
    for (int i = 0 ; i < rawDataCount ; ++i, byteIndex += bytesPerPixel) {

        NSInteger alphaIndex = byteIndex + 3;

        if (rawData[alphaIndex] > 100) {

            for (int row = 1; row <= featherDepth; row++) {
                if (testBorderLayer((long)alphaIndex,
                                    rawData,
                                    (long)rawDataCount,
                                    (long)width,
                                    (long)height,
                                    row)) {

                    int destinationAlpha = 255 / (featherDepth+1) * (row + 1);
                    double alphaDiv =  (double)destinationAlpha / (double)rawData[alphaIndex];

                    rawData[alphaIndex] = destinationAlpha;
                    rawData[alphaIndex-1] = (double)rawData[alphaIndex-1] * alphaDiv;
                    rawData[alphaIndex-2] = (double)rawData[alphaIndex-2] * alphaDiv;
                    rawData[alphaIndex-3] = (double)rawData[alphaIndex-3] * alphaDiv;

//                    switch (row) {
//                        case 1:
//                            rawData[alphaIndex-1] = 255;
//                            rawData[alphaIndex-2] = 0;
//                            rawData[alphaIndex-3] = 0;
//                            break;
//                        case 2:
//                            rawData[alphaIndex-1] = 0;
//                            rawData[alphaIndex-2] = 255;
//                            rawData[alphaIndex-3] = 0;
//                            break;
//                        case 3:
//                            rawData[alphaIndex-1] = 0;
//                            rawData[alphaIndex-2] = 0;
//                            rawData[alphaIndex-3] = 255;
//                            break;
//                        case 4:
//                            rawData[alphaIndex-1] = 127;
//                            rawData[alphaIndex-2] = 127;
//                            rawData[alphaIndex-3] = 0;
//                            break;
//                        case 5:
//                            rawData[alphaIndex-1] = 127;
//                            rawData[alphaIndex-2] = 0;
//                            rawData[alphaIndex-3] = 127;
//                        case 6:
//                            rawData[alphaIndex-1] = 0;
//                            rawData[alphaIndex-2] = 127;
//                            rawData[alphaIndex-3] = 127;
//                            break;
//                        default:
//                            break;
//                    }

                    break;

                }
            }
        }
    }


    CGImageRef newCGImage = CGBitmapContextCreateImage(context);

    UIImage *result = [UIImage imageWithCGImage:newCGImage scale:[self scale] orientation:UIImageOrientationUp];

    CGImageRelease(newCGImage);

    CGContextRelease(context);
    free(rawData);

    return result;
}


//==============================================================================


bool testBorderLayer(long byteIndex,
                     unsigned char *imageData,
                     long dataSize,
                     long pWidth,
                     long pHeight,
                     int border) {


    int width = border * 2 + 1;
    int height = width - 2;

    // run thru border pixels
    // |-|
    // | |
    // |-|

    //top,bot - hor
    for (int i = 1; i < width - 1; i++) {


        long topIndex = byteIndex + 4 * ( - border * pWidth - border + i);
        long botIndex = byteIndex + 4 * ( border * pWidth - border + i);

        long destColl = byteIndex/4 % pWidth - border + i;

        if (destColl > 1 && destColl < pWidth) {
            if (testPoint(topIndex, imageData, dataSize) ||
                testPoint(botIndex, imageData, dataSize)) {
                return true;
            }

        }

    }


    //left,right - ver
    if (byteIndex / 4 % pWidth < pWidth - border - 1) {
        for (int k = 0; k < height; k++) {
            long rightIndex = byteIndex + 4 * ( border - (border) * pWidth + pWidth * k);

            if (testPoint(rightIndex, imageData, dataSize)) {
                return true;
            }
        }
    }

    if (byteIndex / 4 % pWidth > border) {

        for (int k = 0; k < height; k++) {
            long leftIndex = byteIndex + 4 * ( - border - (border) * pWidth + pWidth * k);

            if (testPoint(leftIndex, imageData, dataSize)) {
                return true;
            }
        }
    }

    return false;
}


//==============================================================================


bool testPoint(long pointIndex, unsigned char *imageData, long dataSize) {
    if (pointIndex >= 0 && pointIndex < dataSize * 4 - 1 &&
        imageData[pointIndex] < 30) {
        return true;
    }
    return false;
}

//==============================================================================

对于罕见的评论感到抱歉;)

答案 1 :(得分:0)

我建议看一下苹果推出的这个CIFilter列表,他们得到了一些相当不错的过滤器。

并查看GPUImage。