ios - EZAudio iOS - 将波形保存到图像

标签 ios objective-c cocoa-touch opengl-es glkit

我正在使用适用于 iOS 的 EZAudio 库来处理音频文件的播放并绘制其波形。我想创建一个包含整个波形的 View (EZAudioPlotGL View ,它是 UIView 的子类),然后将其保存为 png。

我遇到了一些问题:

  1. 我为保存快照图像而创建的临时音频图正在绘制到 View ,我不明白这是因为我从未将它添加为 subview 。
  2. tempPlot 仅绘制波形的上半部分(不是我在代码中设置的“镜像”)
  3. 从 tempPlot 保存的 UIImage 仅保存波形开头的一小部分。

问题可以从这些图像中看出:

屏幕应该如何显示(原始音频情节): enter image description here

屏幕看起来如何(显示我不想绘制到屏幕上的 tempPlot): enter image description here

我得到的保存图片应该是tempPlot的副本: enter image description here

可以在这里找到 EZAudio 库:https://github.com/syedhali/EZAudio

如果您想自己查看问题,可以在这里找到我的项目:https://www.dropbox.com/sh/8ilfaofvaa8aq3p/AADU5rOwqzCtEmJz-ePRXIDZa

我对 OpenGL 图形不是很有经验,所以在 EZAudioPlotGL 类中进行的很多工作让我有点头疼。

相关代码如下:

ViewController.m:

@implementation ViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Customizing the audio plot's look
    self.audioPlot.backgroundColor = [UIColor blueColor];
    self.audioPlot.color           = [UIColor whiteColor];
    self.audioPlot.plotType        = EZPlotTypeBuffer;
    self.audioPlot.shouldFill      = YES;
    self.audioPlot.shouldMirror    = YES;

    // Try opening the sample file
    [self openFileWithFilePathURL:[NSURL fileURLWithPath:kAudioFileDefault]];
}
-(void)openFileWithFilePathURL:(NSURL*)filePathURL {
    self.audioFile = [EZAudioFile audioFileWithURL:filePathURL];

    // Plot the whole waveform
    [self.audioFile getWaveformDataWithCompletionBlock:^(float *waveformData, UInt32 length) {
        [self.audioPlot updateBuffer:waveformData withBufferSize:length];
    }];

    //save whole waveform as image
    [self.audioPlot fullWaveformImageForSender:self];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"waveformImage.png"];
    [UIImagePNGRepresentation(self.snapshotImage) writeToFile:filePath atomically:YES];
}
@end

我的 EZAudioPlotGL 类别:

- (void)fullWaveformImageForSender:(ViewController *)sender{
    EZAudioPlotGL *tempPlot = [[EZAudioPlotGL alloc]initWithFrame:self.frame];

    [tempPlot setPlotType:        EZPlotTypeBuffer];
    [tempPlot setShouldFill:      YES];
    [tempPlot setShouldMirror:    YES];
    [tempPlot setBackgroundColor: [UIColor redColor]];
    [tempPlot setColor:           [UIColor greenColor]];

    //plot full waveform on tempPlot
    [sender.audioFile getWaveformDataWithCompletionBlock:^(float *waveformData, UInt32 length) {
        [tempPlot updateBuffer:waveformData withBufferSize:length];

        //tempPlot.glkVC is a getter for the private EZAudioPlotGLKViewController property in tempPlot (added by me in the EZAudioPlotGL class)
        sender.snapshotImage = [((GLKView *)tempPlot.glkVC.view) snapshot];
    }];
}

最佳答案

drawViewHierarchyInRect仅适用于捕获基于 CoreGraphics 的 View 绘图。 (CG 绘图发生在 CPU 上并呈现到主内存中的缓冲区中,因此 CG,又名 UIGraphics,可以从那里直接提取图像。)如果您的 View 绘制它的 View ,它不会帮助您使用 OpenGL 的内容。 (OpenGL 绘图发生在 GPU 上,因此您需要使用 GL 将像素从 GPU 读回主内存,然后才能从中构建图像。)

看起来您的库使用 GLKView 的实例进行绘图。 (查看源代码,EZAudioPlotGL 使用 EZAudioPlotGLKViewController,它创建了自己的 GLKView。)该类又具有一个 snapshot。完成所有繁重工作以从 GPU 取回像素并将它们放入 UIImage 中的方法。

关于ios - EZAudio iOS - 将波形保存到图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23330434/

相关文章:

ios - 从 JSON 调用获取日期时遇到问题

iphone - NSUserDefaults:当 valueforKey 为 ENUM 时如何显示用户默认值

ios - 我的 UIView 没有在旋转时调整宽度

ios - 在每个 View 的底部添加一个按钮 - Swift

ios - 为什么 Main.storyboard 不显示?

ios - 如何添加 NSString 以在定义大小的矩形中查看

ios - 缓存 URL 图片 iphone UITableview

ios - 警告 : CLSLog has been used before (or concurrently with) Crashlytics initialization and cannot be recorded

ios - (NSObject, AnyObject) 不可转换为 DictionaryIndex<NSObject, AnyObject>

c++ - 修剪十分之一和千分之几的算法