【问题标题】:Which graphics library and functions for overlaying text and graphics on images哪些图形库和函数用于在图像上叠加文本和图形
【发布时间】:2012-08-18 02:40:48
【问题描述】:

我需要编写一个可以拍照的应用程序,然后我希望能够预览它并覆盖图形和一些文本,然后将其保存回图像库。

因此,我的用户将启动我的应用程序,然后该应用程序将使用 UIImagePickerController 访问相机并通过委托获取图像数据。

然后我想将它显示在屏幕上,然后显示控件以添加可见图像(或特别是徽标),并让用户可以选择添加一两行文本,然后将这些文本定位在图片。

然后用户将单击保存,生成的合成图像将被写入相机胶卷/照片库,然后用户可以根据需要将图像上传到 twitter、facebook 等(我不希望实现 OAuth2 的开销这可能是别人的问题)。

那么,我需要知道的是 SDK 中提供的众多库中的哪一个可以让我这样做? CG图像?鉴于我的叠加徽标将是透明的 PNG,我如何将一个叠加在另一个上?

我听说您可以使用 CALayer 进行演示,但我不知道您如何将所有图层一起抓取(将它们展平)。

在 PHP 中,您会使用 imagecopymerge() 之类的东西,但我无法找出等价物。

我不想将数据传递给网络服务器并返回,因为我知道它可以在本地完成。

谢谢

【问题讨论】:

    标签: ios graphics uiimage core-graphics


    【解决方案1】:

    在图像上添加文本我相信您可以使用文本字段来获取输入,然后将文本放入标签中。这部分可以通过几种不同的方式完成,但相当容易。

    就抓取所有图层的组合图像而言,您可以使用 Quartz。

    每个UIWindow(继承自UIView)和UIView都由一个CALayer支持。 CALayer/-renderInContext: 方法允许您将层及其子层渲染到图形上下文。因此,要获取整个屏幕的快照,您可以遍历屏幕上的每个窗口并将其层层次结构渲染到目标上下文。完成后可以通过UIGraphicsGetImageFromCurrentImageContext函数获取截图,如下图。

    请注意,CALayer/-renderInContext: 仅捕获您的 UIKit 和 Quartz 绘图。它不捕获 OpenGL ES 或视频内容。

    #import <QuartzCore/QuartzCore.h>
    

    .....

    - (UIImage*)screenshot 
    {
        // Create a graphics context with the target size
        // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
        // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
        CGSize imageSize = [[UIScreen mainScreen] bounds].size;
        if (NULL != UIGraphicsBeginImageContextWithOptions)
            UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
        else
            UIGraphicsBeginImageContext(imageSize);
    
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        // Iterate over every window from back to front
        for (UIWindow *window in [[UIApplication sharedApplication] windows]) 
        {
            if (![window respondsToSelector:@selector(screen)] || [window screen] == [UIScreen mainScreen])
            {
                // -renderInContext: renders in the coordinate space of the layer,
                // so we must first apply the layer's geometry to the graphics context
                CGContextSaveGState(context);
                // Center the context around the window's anchor point
                CGContextTranslateCTM(context, [window center].x, [window center].y);
                // Apply the window's transform about the anchor point
                CGContextConcatCTM(context, [window transform]);
                // Offset by the portion of the bounds left of and above the anchor point
                CGContextTranslateCTM(context,
                                      -[window bounds].size.width * [[window layer] anchorPoint].x,
                                      -[window bounds].size.height * [[window layer] anchorPoint].y);
    
                // Render the layer hierarchy to the current context
                [[window layer] renderInContext:context];
    
                // Restore the context
                CGContextRestoreGState(context);
            }
        }
    
        // Retrieve the screenshot image
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    
        UIGraphicsEndImageContext();
    
        return image;
    }
    

    至于上传到 Facebook 和 Twitter,请查看 ShareKit。它是一个拖放库,用于与 Facebook、Twitter、Tumblr、电子邮件等共享。拥有它会为您的应用程序增加价值。我建议实施它。

    【讨论】:

    • 我喜欢这个想法,这是否可以适用于特定的 UIView,所以如果我在 iPad 上编写应用程序,我可以在右侧的缩放 UIView 中显示组合图像的预览,并且左侧的选项,但只捕获所有 UIView 的?我猜这将是迭代子视图的情况?
    • 正确,不是遍历屏幕的所有窗口,而是遍历 UIView 的。
    • 谢谢 cory,我刚刚发现了您指向 ShareKit 的链接,我肯定会调查一下,目前,这是一个私人使用的应用程序(这不都是他们开始的方式吗)但可能会在我试用后不久发布。一个 UIView 将包含一个 UIImage 并且一个 UIImage 可以设置为缩放到包含的视图,对吗?我试图想办法让人们将徽标放到设备上,但只是将其添加到照片库并从那里选择它并提供位置控制似乎是最友好的 UI 方式。
    • 正确的 UIImage 可以设置为缩放到包含视图。我不确定你所说的“在”设备上的标志是什么意思。如果是同一个徽标,我会在应用程序中包含该图像。
    猜你喜欢
    • 2015-08-30
    • 1970-01-01
    • 2020-03-06
    • 2018-12-25
    • 2016-09-02
    • 1970-01-01
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多