2016-08-29 7 views
4

У меня есть это ImageProcessor в Swift (это не мое), я пытаюсь использовать его с некоторыми фильтрами, которые я создал, но, пытаясь попробовать, я заметил, что был случайный шум.Обработка изображений с Swift имеет случайные эффекты

Чтобы проверить это, я сделал собственный фильтр NoFilter, который ничего не делает.

public class NoFilter : ImageFilterProtocol{ 
    public func apply(pixel: Pixel) -> Pixel { 
     return pixel 
    } 
} 

Это должно выводить то же изображение, которое оно получает, а иногда оно дает случайные ошибки внутри изображения.

Например:

enter image description here

Обратите внимание, как это тот же код и генерирует различные ошибки каждый раз. В конце вопроса есть ссылка, чтобы попробовать это самостоятельно, каждый раз, когда она работает, может быть иная. Что это может быть причиной этого?

В настоящее время поток программы это, что ImageProcessor принимает и изображение и преобразует его в RGBAImage, а затем, когда apply вызывается с помощью фильтра, он применяет этот фильтр для каждого пикселя в RGBAImage (который в данном случае является нет фильтр). И, наконец, когда вызывается getImage, он преобразует RGBAImage обратно в UIImage. Это говорит о том, что может быть проблема с преобразованием из и/или в RGBAImage, но я не могу найти с ним ничего плохого.

public struct RGBAImage { 
    public var pixels: UnsafeMutableBufferPointer<Pixel> 

    public var width: Int 
    public var height: Int 

    public init?(image: UIImage) { 
     guard let cgImage = image.CGImage else { return nil } 

     // Redraw image for correct pixel format 
     let colorSpace = CGColorSpaceCreateDeviceRGB() 

     var bitmapInfo: UInt32 = CGBitmapInfo.ByteOrder32Big.rawValue 
     bitmapInfo |= CGImageAlphaInfo.PremultipliedLast.rawValue & CGBitmapInfo.AlphaInfoMask.rawValue 

     width = Int(image.size.width) 
     height = Int(image.size.height) 
     let bytesPerRow = width * 4 

     let imageData = UnsafeMutablePointer<Pixel>.alloc(width * height) 

     guard let imageContext = CGBitmapContextCreate(imageData, width, height, 8, bytesPerRow, colorSpace, bitmapInfo) else { return nil } 
     CGContextDrawImage(imageContext, CGRect(origin: CGPointZero, size: image.size), cgImage) 

     pixels = UnsafeMutableBufferPointer<Pixel>(start: imageData, count: width * height) 
    } 

    public func toUIImage() -> UIImage? { 
     let colorSpace = CGColorSpaceCreateDeviceRGB() 
     var bitmapInfo: UInt32 = CGBitmapInfo.ByteOrder32Big.rawValue 
     bitmapInfo |= CGImageAlphaInfo.PremultipliedLast.rawValue & CGBitmapInfo.AlphaInfoMask.rawValue 

     let bytesPerRow = width * 4 

     let imageContext = CGBitmapContextCreateWithData(pixels.baseAddress, width, height, 8, bytesPerRow, colorSpace, bitmapInfo, nil, nil) 

     guard let cgImage = CGBitmapContextCreateImage(imageContext) else {return nil} 
     let image = UIImage(CGImage: cgImage) 

     return image 
    } 
} 

This is the code, что я в настоящее время тестирования, пожалуйста, попробуйте.

Любая идея?

EDIT: Загрузили мой код в git, чтобы его можно было проверить онлайн.

+0

Измените свой вопрос, включив соответствующий код в MCVE. Никто не хочет скачивать неизвестные файлы со странных URL-адресов. –

+0

@RoboticCat достаточно справедливо. исправлено. – rr1g0

ответ

2

Вы забываете очистить свой контекст изображения, когда рисуете его изображение. Попробуйте добавить вызов CGContextClearRect:

let rect = CGRect(origin: CGPointZero, size: image.size) 
CGContextClearRect(imageContext, rect) // Avoid undefined pixels! 
CGContextDrawImage(imageContext, rect, cgImage) 

Это позволит избежать неопределенных пикселей выглядывают из-под прозрачной области вашего изображения.

+0

Это сработало! Благодарю. – rr1g0