如何使用 Opengl ES 裁剪图像?

Posted

技术标签:

【中文标题】如何使用 Opengl ES 裁剪图像?【英文标题】:How can I use Open GL ES to crop image? 【发布时间】:2014-11-01 12:25:57 【问题描述】:

所以我在处理图像裁剪时遇到了一些问题。我知道两种可能的方法:UIGraphicsBeginImageContextWithOptions 结合drawAtPoint:blendMode: 方法和CGImageCreateWithImageInRect。它们都有效,但有一些严重的缺点:第一种方法需要很多时间(在我的情况下大约 7 秒)和内存(我收到内存警告)(假设我裁剪用 iPhone 相机拍摄的图像);第二个以旋转图像结束,因此您需要放置一堆代码来击败我不想要的这种行为。我想知道的是,例如,苹果内置的“照片”应用程序的编辑功能,或者 Aviary 或任何其他照片编辑器是如何工作的。考虑苹果的编辑器(ios 8),您可以旋转图像,更改裁剪矩形,它们在裁剪矩形之外也有模糊(!)等等,但是当您应用裁剪时,它最多需要 8 mb 的内存并且它会立即发生。他们是怎么做到的?

我唯一的想法是他们利用了 GPU 的潜力(例如 Aviary)。那么,如果我们将所有这些问题合二为一,我怎样才能使用 Open GL 让裁剪操作变得不那么痛苦呢?我从来没有使用过它,所以欢迎任何 tuts、链接和来源。提前谢谢你。

【问题讨论】:

OpenGL 及其衍生品是用于绘制东西的 API,最终会出现在屏幕上。核心目的是用于实时图形渲染。您的任务是通用图像操作,这可以通过 OpenGL 实现,但通常使用专用图像操作库更容易完成。 @datenwolf 好的,请问您能说出其中的一些吗? 【参考方案1】:

正如已经提到的,这很可能不应该用 openGL 完成,但即使......

大多数人遇到的问题是获取应该在其中显示图像的矩形,解决方案如下所示:

- (CGRect)fillSizeForSource:(CGRect)source target:(CGRect)target

    if(source.size.width/source.size.height > target.size.width/target.size.height)
    
        // keep target height and make the width larger
        CGSize newSize = CGSizeMake(target.size.height * (source.size.width/source.size.height), target.size.height);
        return CGRectMake((target.size.width-newSize.width)*.5f, .0f, newSize.width, newSize.height);
    
    else
    
        // keep target width and make the height larger
        CGSize newSize = CGSizeMake(target.size.width, target.size.width * (source.size.height/source.size.width));
        return CGRectMake(.0f, (target.size.height-newSize.height)*.5f, newSize.width, newSize.height);
    


- (CGRect)fitSizeForSource:(CGRect)source target:(CGRect)target

    if(source.size.width/source.size.height < target.size.width/target.size.height)
    
        // keep target height and make the width smaller
        CGSize newSize = CGSizeMake(target.size.height * (source.size.width/source.size.height), target.size.height);
        return CGRectMake((target.size.width-newSize.width)*.5f, .0f, newSize.width, newSize.height);
    
    else
    
        // keep target width and make the height smaller
        CGSize newSize = CGSizeMake(target.size.width, target.size.width * (source.size.height/source.size.width));
        return CGRectMake(.0f, (target.size.height-newSize.height)*.5f, newSize.width, newSize.height);
    

我没有测试这个。

或者由于您在 iOS 上,只需创建一个具有所需大小的图像视图,向其中添加图像,然后获取图像的屏幕截图。

【讨论】:

所以这些方法会将我的源矩形转换为 CGImageCreateWithImageInRect 将使用的矩形? 此函数创建一个具有给定矩形的子图像,当其中一个尺寸等于原始图像时,它应该使用 fit 方法。换句话说:不,因为它不会调整图像大小。您可以使用这些方法来获取将图像绘制到自定义核心图形上下文的位置的矩形(目标大小应该是上下文大小)。或者您可以使用它们通过 openGL 重绘图像。或者使用目标矩形创建一个视图,并使用 rect 方法添加一个子视图图像视图以获得相同的结果...

以上是关于如何使用 Opengl ES 裁剪图像?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 OpenGL ES 2.0 中使用 png 图像纹理立方体?

使用 lwjgl/opengl 进行简单裁剪

在 cocos2d 中使用 opengl-es 进行圆形裁剪

OpenGL ES 1 裁剪对象

使用 OpenGL ES 2.0 绘制 2D 图像

如何使用带有 OpenGL ES 的 android 相机工作?