我正在使用适用于 iOS 的 EZAudio 库来处理音频文件的播放并绘制其波形。我想创建一个包含整个波形的 View (EZAudioPlotGL View ,它是 UIView 的子类),然后将其保存为 png。
我遇到了一些问题:
- 我为保存快照图像而创建的临时音频图正在绘制到 View ,我不明白这是因为我从未将它添加为 subview 。
- tempPlot 仅绘制波形的上半部分(不是我在代码中设置的“镜像”)
- 从 tempPlot 保存的 UIImage 仅保存波形开头的一小部分。
问题可以从这些图像中看出:
屏幕应该如何显示(原始音频情节):
屏幕看起来如何(显示我不想绘制到屏幕上的 tempPlot):
我得到的保存图片应该是tempPlot的副本:
可以在这里找到 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/