gpt4 book ai didi

从 UIImages 创建 mov 时的 iOS 绿色边框

转载 作者:可可西里 更新时间:2023-11-01 05:56:37 32 4
gpt4 key购买 nike

我正在使用下面的代码获取一系列 UIImage,并将它们转换成一个 mov。出于某种原因,我一直在底部或右侧获得绿色边框,具体取决于它是风景照片还是肖像照片。图片为 215x320。

如何去除绿色边框?有没有更好的方法从 UIImages 创建 .mov?

- (void)createMov
{
UIImage *first = [self.videoFrames objectAtIndex:0];

CGSize frameSize = first.size;

NSError *error = nil;
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:
[NSURL fileURLWithPath:fileName] fileType:AVFileTypeQuickTimeMovie
error:&error];

if (error) {
NSLog(@"error creating AssetWriter: %@",[error description]);
}

int numPixels = first.size.width * first.size.height;
int bitsPerSecond = numPixels * 11.04;


NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:frameSize.width], AVVideoWidthKey,
[NSNumber numberWithInt:frameSize.height], AVVideoHeightKey,
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:bitsPerSecond], AVVideoAverageBitRateKey,
[NSNumber numberWithInteger:30], AVVideoMaxKeyFrameIntervalKey,
nil], AVVideoCompressionPropertiesKey,
nil];

AVAssetWriterInput* writerInput = [[AVAssetWriterInput
assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings] retain];

NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
[attributes setObject:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB] forKey: (NSString*)kCVPixelBufferPixelFormatTypeKey];
[attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.width] forKey:(NSString*)kCVPixelBufferWidthKey];
[attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.height] forKey:(NSString*)kCVPixelBufferHeightKey];

AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
sourcePixelBufferAttributes:attributes];

[videoWriter addInput:writerInput];

// fixes all errors
writerInput.expectsMediaDataInRealTime = YES;

//Start a session:
BOOL start = [videoWriter startWriting];
NSLog(@"Session started? %d", start);
[videoWriter startSessionAtSourceTime:kCMTimeZero];


// Writing.
CVPixelBufferRef buffer = NULL;
buffer = [self pixelBufferFromCGImage:[first CGImage]];
BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];

if (result == NO) //failes on 3GS, but works on iphone 4
NSLog(@"failed to append buffer");

if(buffer)
CVBufferRelease(buffer);

[NSThread sleepForTimeInterval:0.05];

int fps = [Utils frameRate];

int i = 0;
for (UIImage *imgFrame in self.videoFrames) {
i = [self addFrame:adaptor videoWriter:videoWriter buffer:buffer imgFrame:imgFrame i:i fps:fps];
}

//Finish the session:
[writerInput markAsFinished];
[videoWriter finishWriting];
CVPixelBufferPoolRelease(adaptor.pixelBufferPool);
[videoWriter release];
[writerInput release];
}


- (int)addFrame:(AVAssetWriterInputPixelBufferAdaptor *)adaptor videoWriter:(AVAssetWriter *)videoWriter buffer:(CVPixelBufferRef)buffer imgFrame:(UIImage *)imgFrame i:(int)i fps: (float)fps
{
if (adaptor.assetWriterInput.readyForMoreMediaData) {

i++;
NSLog(@"inside for loop %d",i);
CMTime frameTime = CMTimeMake(1, fps);
CMTime lastTime=CMTimeMake(i, fps);
CMTime presentTime=CMTimeAdd(lastTime, frameTime);

buffer = [self pixelBufferFromCGImage:[imgFrame CGImage]];
BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];

if (result == NO) { //fails on 3GS, but works on iphone 4
NSLog(@"failed to append buffer");
NSLog(@"The error is %@", [videoWriter error]);
}

if (buffer) {
CVBufferRelease(buffer);
}

[NSThread sleepForTimeInterval:0.05];
} else {
NSLog(@"error");
i--;
}
[NSThread sleepForTimeInterval:0.02];

return i;
}


- (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image
{
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
nil];
CVPixelBufferRef pxbuffer = NULL;

CVPixelBufferCreate(kCFAllocatorDefault, CGImageGetWidth(image),
CGImageGetHeight(image), kCVPixelFormatType_32ARGB, (CFDictionaryRef) options,
&pxbuffer);

CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
size_t rowBytes = CVPixelBufferGetBytesPerRow(pxbuffer);


CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata, CGImageGetWidth(image),
CGImageGetHeight(image), 8, rowBytes, rgbColorSpace,
kCGImageAlphaNoneSkipFirst);

CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));


CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);

CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

return pxbuffer;
}

最佳答案

看来我遇到了类似的问题,在阅读了以下两篇文章后,我的脑海中突然有了一个想法。

http://forum.videohelp.com/threads/314973-green-line-at-bottom-of-video-window

http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC#Features

NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithUnsignedLong:sourceWidth], AVVideoWidthKey,
[NSNumber numberWithUnsignedLong:sourceHeight], AVVideoHeightKey,
nil];
AVAssetWriterInput *writerInput =
[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];

在开始使用 AVAssertWriter 写入数据之前,请使用以下方法重新设置 sourceWidthsourceHeight:

size_t fixedLineValue(size_t sourceValue){
size_t divide = sourceValue%4;
size_t finalValue = sourceValue;
if (divide) {
finalValue=(sourceValue/4+1)*4;
}
return finalValue;
}

我不清楚为什么要这样做,但在那之后,丑陋的绿色边框被移除了。如果有更好的答案,请发表评论,让我们知道。谢谢。

关于从 UIImages 创建 mov 时的 iOS 绿色边框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14187240/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com