简体   繁体   English

EZAudio iOS-将波形保存到图像

[英]EZAudio iOS - Save Waveform to Image

I'm using the EZAudio library for iOS to handle the playback of an audio file and draw its waveform. 我正在使用iOS的EZAudio库来处理音频文件的播放并绘制其波形。 I'd like to create aa view with the entire waveform (an EZAudioPlotGL view, which is a subclass of UIView) and then save it as a png. 我想用整个波形创建一个视图(EZAudioPlotGL视图,这是UIView的子类),然后将其另存为png。

I'm having a couple problems with this: 我对此有几个问题:

  1. The temporary audio plot I'm creating to save the snapshot image is drawing to the view, which I don't understand because I never add it as a subview. 我创建的用于保存快照图像的临时音频图正在绘制到视图中,这是我无法理解的,因为我从未将其添加为子视图。
  2. The tempPlot is only drawing the top half of the waveform (not "mirrored" as I set it in the code) tempPlot仅绘制波形的上半部分(不是我在代码中设置的“镜像”)
  3. The UIImage being saved from the tempPlot is only saving a short portion of the beginning of the waveform. 从tempPlot中保存的UIImage仅保存了波形开始的一小部分。

The problems can be seen in these images: 这些图像中可以看到这些问题:

How the screen should look after (the original audio plot): 屏幕的外观如何(原始音频图): 在此处输入图片说明

How the screen does look (showing the tempPlot I don't want to draw to the screen): 屏幕的外观(显示我不想绘制到屏幕上的tempPlot): 在此处输入图片说明

The saved image I get out that should be a copy of tempPlot: 我得到的保存图像应该是tempPlot的副本: 在此处输入图片说明

The EZAudio library can be found here: https://github.com/syedhali/EZAudio 可以在这里找到EZAudio库: https : //github.com/syedhali/EZAudio

And my project can be found here, if you want to see the problem for yourself: https://www.dropbox.com/sh/8ilfaofvaa8aq3p/AADU5rOwqzCtEmJz-ePRXIDZa 如果您想亲自了解问题,可以在这里找到我的项目: https : //www.dropbox.com/sh/8ilfaofvaa8aq3p/AADU5rOwqzCtEmJz-ePRXIDZa

I'm not very experienced with OpenGL graphics, so a lot of the work going on inside the EZAudioPlotGL class is a bit over my head. 我对OpenGL图形的经验不是很丰富,因此EZAudioPlotGL类中正在进行的许多工作都有些麻烦。

Here's the relevant code: 以下是相关代码:

ViewController.m: 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

My Category of EZAudioPlotGL: 我的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 only works for capturing CoreGraphics-based view drawing. drawViewHierarchyInRect仅适用于捕获基于CoreGraphics的视图绘图。 (CG drawing happens on the CPU and renders into a buffer in main memory, so CG, aka UIGraphics , can just slurp an image out of there.) It won't help you if your view draws its content using OpenGL. (CG绘制发生在CPU上,并渲染到主内存中的缓冲区中,因此CG,也称为UIGraphics ,只能从那里提取图像。)如果您的视图使用OpenGL绘制其内容,它将无济于事。 (OpenGL drawing happens on the GPU, so you need to use GL to read pixels back from the GPU to main memory before you can build an image out of them.) (OpenGL绘制在GPU上进行,因此您需要使用GL将像素从GPU读取回主内存,然后才能从它们中构建图像。)

It looks like your library does its drawing with an instance of GLKView . 看起来您的库使用GLKView实例进行GLKView (Poking around in the source, EZAudioPlotGL uses EZAudioPlotGLKViewController , which creates its own GLKView .) That class, in turn, has a snapshot method that does all the heavy lifting to get pixels back from the GPU and put them in a UIImage . (在源代码中EZAudioPlotGLEZAudioPlotGL使用EZAudioPlotGLKViewController ,它创建了自己的GLKView 。)该类又具有一个snapshot方法,该方法可以完成所有繁重的工作,以从GPU取回像素并将其放入UIImage

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM