iOS:在 uiimage 上具有发光/阴影效果的羽毛

2023-12-07

我正在尝试找到一种方法来应用带有阴影的羽毛效果UIImage, not UIImageView我在iOS上遇到过,目前还没有找到完美的解决方案。我有一个想法,这可以通过屏蔽来完成,但我对这很陌生CoreGraphics.

如果有人可以帮忙的话。

Thanks.


好的,所以: 我一直在寻找同样的东西,但不幸的是没有运气。 我决定创建自己的羽毛代码。

将此代码添加到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;
}

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

抱歉很少发表评论;)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS:在 uiimage 上具有发光/阴影效果的羽毛 的相关文章

随机推荐

  • 如何忽略 xml 命名空间?

    我有一个测试 xml 文件 如下所示
  • 如何使用 PHP 将网页放入变量中

    我想从网上下载一个页面 当您使用像 Firefox 这样的简单浏览器时 这是允许的 但是当我使用 file get contents 时 服务器拒绝并回复说它理解该命令 但不允许此类下载 那么该怎么办 我想我在一些脚本 在 Perl 上 中
  • Java 中的 HashMap 实现。桶索引计算是如何进行的?

    我正在研究实施HashMap在Java中 我陷入了困境 怎么样indexFor函数计算 static int indexFor int h int length return h length 1 Thanks 哈希本身是通过以下方式计算的
  • 自定义 ArrayAdapter 上的可点击行

    我为 ListView 制作了一个自定义 ArrayAdapter 以便使用某些元素自定义列表的行 我遇到的问题是我无法选择一个项目 单击时没有任何反应 我必须在自定义 ArrayAdapter 中实现它吗 它只有一个构造函数和一个 get
  • 如何在母版页标题中包含jquery而不出现路径问题?

    我已经尝试过这个 scripts jquery 1 5 1 min js gt gt
  • 是否可以通过 url 将文件上传到应用程序引擎上的云存储而不写入磁盘?

    要将文件从url上传到云存储系统 通常需要将该文件下载到服务器上 然后将其上传到云存储 对于大文件 可能需要将文件写入磁盘而不是内存 由于应用程序引擎不支持在磁盘上写入 因此还有其他选项可以在应用程序引擎上执行此操作吗 我知道托管虚拟机是一
  • 无法在 WinForms 设计器中选择 Infragistics 控件

    我刚刚升级了 2006 年至 2011 年一个项目的 Infragistics 控件 现在 如果我打开包含任何 Infragistics 控件的表单的设计器 Infragistics 控件将显示在表单设计器下方的单独面板中 并且我无法在设计
  • CTR 中的 AES 如何与 PyCrypto 一起用于 Python?

    我正在使用 python 2 7 1 我想在 CTR 模式下使用 AES 进行加密 我为 python 安装了 PyCrypto 库 我写了以下代码 secret os urandom 16 crypto AES new os urando
  • 如何使用本地构建的 nuget 包进行调试?

    我们有几个项目使用共享的公共库 内部的 非公共的 C net 项目 使用 Visual Studio 设置作为解决方案 Solution A gt Common Library Nuget Package Solution B 一般来说 这
  • 单击按钮 Javascript 即可触发文件下载,其中包含 DOM 中的内容

    我想下载一个从 DOM 元素创建的文件 因此 用户单击网页上的按钮 它会调用 JavaScript 方法 该方法可以获取 DOM 元素的内容并提示用户下载 我能够获取 Javascript Var 中 DOM 元素的内容 但不确定如何进一步
  • 在当前 HTTPContext 中生成新的 ASP.NET 会话

    对我们正在开发的一些产品进行渗透测试的结果是 当时看似 容易 解决的问题却变得棘手 当然不是应该的 我的意思是为什么会这样为当前生成一个全新的会话HTTPContext有那么难吗 奇怪 不管怎样 我写了一个厚颜无耻的小实用程序类来 就这么做
  • Android 切换按钮自定义外观

    我一直在尝试自定义切换按钮的外观 但没有成功 这是我想要的样子 有人可以给我一个教程吗 在res drawable中创建toggle selector xml
  • 为什么 JSON.parse("string") 失败

    根据JSON规范字符串是合法的 JSON 值 那么为什么会发生这种情况呢 你实际上是在传递赤裸裸的话语string到函数中 这当然不是有效的 JSON 要真正传递value string 你需要小心你的 JavaScript 尝试这个 JS
  • 查看完整网站,而非 iPhone 上的移动版本

    我有一个脚本可以检测您是否是 iPhone 用户并重定向到对 iPhone 更友好的页面 这很好用 但有一个问题 惯例是让用户能够查看full网页 但是 如果我链接到根目录 显然重定向会将它们发送到移动版本 有关如何包含的任何想法 请点击以
  • 将多行数据合并到一列中

    我有一个这样的数据 year Male 1 2011 8 2 2011 1 3 2011 4 4 2012 3 5 2012 12 6 2012 9 7 2013 4 8 2013 3 9 2013 3 我需要将 2011 年的数据分组到一
  • 如何在“func renderer(SCNSceneRenderer, nodeFor: ARAnchor) -> SCNNode”中旋转 SCNNode?

    因此 我能够在锚点位置放置一个盒子节点 现在 如何旋转场景中的 SCNNode 我试图修改节点的变换和 eulerAngles 但它们没有效果 func renderer renderer SCNSceneRenderer nodeFor
  • 位图图像处理

    我想使用 LockBits 方法替换 GetPixel 和 SetPixel 所以我遇到了这个F 惰性像素读取 open System Drawing open System Drawing Imaging let pixels image
  • Xquery 中的标记化

    如何标记特殊字符 例如 and 在 xquery 正如我正在努力Tokenize这些特殊字符 我无法做到这一点 你能建议我解决这个问题吗 您必须像在 XML 中一样转义 符号 tokenize string amp 或者 您也可以使用它的
  • 通过触摸或手势识别移动 RecyclerView

    我正在尝试移动和扩展 RecyclerView 以便内容在触摸输入的基础上占据全屏 我希望 RecyclerView 保持左右滚动的能力 我无法让 GestureDetector 与 RecyclerView 一起正常工作 捕获 onScr
  • iOS:在 uiimage 上具有发光/阴影效果的羽毛

    我正在尝试找到一种方法来应用带有阴影的羽毛效果UIImage not UIImageView我在iOS上遇到过 目前还没有找到完美的解决方案 我有一个想法 这可以通过屏蔽来完成 但我对这很陌生CoreGraphics 如果有人可以帮忙的话