CGBitmapContextCreate:不支持的参数组合。如何传递kCGImageAlphaNoneSkipFirst [英] CGBitmapContextCreate: unsupported parameter combination. How to pass kCGImageAlphaNoneSkipFirst

查看:770
本文介绍了CGBitmapContextCreate:不支持的参数组合。如何传递kCGImageAlphaNoneSkipFirst的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最初在Obj-写了这个应用程序( GitHub ) C,但需要将其转换为Swift。在转换时,我一直无法获得创建位图的上下文。

I originally wrote this App (GitHub) in Obj-C, but need to convert it to Swift. Upon converting I've been having trouble getting the Context for the Bitmap created.

错误消息:

Whiteboard[2833] <Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 24 bits/pixel; 3-component color space; kCGImageAlphaNone; 1500 bytes/row.

原来我有这个:

self.cacheContext = CGBitmapContextCreate (self.cacheBitmap, size.width, size.height, 8, bitmapBytesPerRow, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst);

现在我有:

self.cacheContext = CGBitmapContextCreate(self.cacheBitmap!, UInt(size.width), UInt(size.height), 8, bitmapBytesPerRow, CGColorSpaceCreateDeviceRGB(), CGBitmapInfo.ByteOrder32Little);

我认为这个问题与 CGBitmapInfo.ByteOrder32Little ,但我不知道该通过什么。有没有办法将 kCGImageAlphaNoneSkipFirst 作为 CGBitmapInfo 传递?

I believe the issue has to do with CGBitmapInfo.ByteOrder32Little, but I'm not sure what to pass. Is there a way to pass kCGImageAlphaNoneSkipFirst as a CGBitmapInfo?

完整来源:

//
//  WhiteBoard.swift
//  Whiteboard
//

import Foundation
import UIKit


class WhiteBoard: UIView {

    var hue: CGFloat
    var cacheBitmap: UnsafeMutablePointer<Void>?
    var cacheContext: CGContextRef?


    override init(frame: CGRect) {
        self.hue = 0.0;

        // Create a UIView with the size of the parent view
        super.init(frame: frame);

        // Initialize the Cache Context of the bitmap
        self.initContext(frame);

        // Set the background color of the view to be White
        self.backgroundColor = UIColor.whiteColor();

        // Add a Save Button to the bottom right corner of the screen
        let buttonFrame = CGRectMake(frame.size.width - 50, frame.size.height - 30, 40, 25);
        let button = UIButton();
        button.frame = buttonFrame;
        button.setTitle("Save", forState: .Normal);
        button.setTitleColor(UIColor.blueColor(), forState: .Normal);
        button.addTarget(self, action: "downloadImage", forControlEvents: .TouchUpInside);

        // Add the button to the view
        self.addSubview(button);
    }

    required init(coder aDecoder: NSCoder) {
        self.hue = 0.0;

        super.init(coder: aDecoder)
    }

    func initContext(frame: CGRect)-> Bool {
        let size = frame.size; // Get the size of the UIView
        var bitmapByteCount: UInt!
        var bitmapBytesPerRow: UInt!

        // Calculate the number of bytes per row. 4 bytes per pixel: red, green, blue, alpha
        bitmapBytesPerRow = UInt(size.width * 4);

        // Total Bytes in the bitmap
        bitmapByteCount = UInt(CGFloat(bitmapBytesPerRow) * size.height);

        // Allocate memory for image data. This is the destination in memory where any
        // drawing to the bitmap context will be rendered
        self.cacheBitmap = malloc(bitmapByteCount);


        // Create the Cache Context from the Bitmap
        self.cacheContext = CGBitmapContextCreate(self.cacheBitmap!, UInt(size.width), UInt(size.height), 8, bitmapBytesPerRow, CGColorSpaceCreateDeviceRGB(), CGBitmapInfo.ByteOrder32Little);

        // Set the background as white
        CGContextSetRGBFillColor(self.cacheContext, 1.0, 1.0, 1.0, 1.0);
        CGContextFillRect(self.cacheContext, frame);
        CGContextSaveGState(self.cacheContext);

        return true;
    }

    // Fired everytime a touch event is dragged
    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
        let touch = touches.anyObject() as UITouch;

        self.drawToCache(touch);
    }

    // Draw the new touch event to the cached Bitmap
    func drawToCache(touch: UITouch) {
        self.hue += 0.005;
        if(self.hue > 1.0) {
            self.hue = 0.0;
        }

        // Create a color object of the line color
        let color = UIColor(hue: CGFloat(self.hue), saturation: CGFloat(0.7), brightness: CGFloat(1.0), alpha: CGFloat(1.0));

        // Set the line size, type, and color
        CGContextSetStrokeColorWithColor(self.cacheContext, color.CGColor);
        CGContextSetLineCap(self.cacheContext, kCGLineCapRound);
        CGContextSetLineWidth(self.cacheContext, CGFloat(15));

        // Get the current and last touch point
        let lastPoint = touch.previousLocationInView(self) as CGPoint;
        let newPoint = touch.locationInView(self) as CGPoint;

        // Draw the line
        CGContextMoveToPoint(self.cacheContext, lastPoint.x, lastPoint.y);
        CGContextAddLineToPoint(self.cacheContext, newPoint.x, newPoint.y);
        CGContextStrokePath(self.cacheContext);

        // Calculate the dirty pixels that needs to be updated
        let dirtyPoint1 = CGRectMake(lastPoint.x-10, lastPoint.y-10, 20, 20);
        let dirtyPoint2 = CGRectMake(newPoint.x-10, newPoint.y-10, 20, 20);

        self.setNeedsDisplay();

        // Only update the dirty pixels to improve performance
        //self.setNeedsDisplayInRect(dirtyPoint1);
        //self.setNeedsDisplayInRect(dirtyPoint2);
    }

    // Draw the cachedBitmap to the UIView
    override func drawRect(rect: CGRect) {
        // Get the current Graphics Context
        let context = UIGraphicsGetCurrentContext();

        // Get the Image to draw
        let cacheImage = CGBitmapContextCreateImage(self.cacheContext);

        // Draw the ImageContext to the screen
        CGContextDrawImage(context, self.bounds, cacheImage);
    }

    // Download the image to the camera roll
    func downloadImage() {
        // Get the Image from the CGContext
        let image = UIImage(CGImage: CGBitmapContextCreateImage(self.cacheContext));

        // Save the Image to their Camera Roll
        UIImageWriteToSavedPhotosAlbum(image, self, "image:didFinishSavingWithError:contextInfo:", nil);
    }

    func image(image: UIImage, didFinishSavingWithError error: NSError, contextInfo: UnsafeMutablePointer<Void>) {
        if(!error.localizedDescription.isEmpty) {
            UIAlertView(title: "Error", message: "Error Saving Photo", delegate: nil, cancelButtonTitle: "Ok").show();
        }
    }

}


推荐答案

在Objective-C中,您只需转换为其他枚举类型,如下所示:

In Objective-C, you would simply cast to the other enum type, like this:

(CGBitmapInfo)kCGImageAlphaNoneSkipFirst

在Swift中,你必须这样做:

In Swift, you have to do it like this:

CGBitmapInfo(CGImageAlphaInfo.NoneSkipFirst.rawValue)

欢迎来到Swift数字的狂野和古怪世界。您必须使用 rawValue 从原始CGImageAlphaInfo枚举中提取数值;现在你可以在CGBitmapInfo枚举的初始值设定项中使用该数值。

Welcome to the wild and wacky world of Swift numerics. You have to pull the numeric value out of the original CGImageAlphaInfo enumeration with rawValue; now you can use that numeric value in the initializer of the CGBitmapInfo enumeration.

编辑它在iOS 9 / Swift 2.0中更简单,你在那里只需将 CGImageAlphaInfo.NoneSkipFirst.rawValue 直接传递给CGBitmapContextCreate,现在只需要一个整数。

EDIT It's much simpler in iOS 9 / Swift 2.0, where you can just pass CGImageAlphaInfo.NoneSkipFirst.rawValue directly into CGBitmapContextCreate, which now just expects an integer at this spot.

这篇关于CGBitmapContextCreate:不支持的参数组合。如何传递kCGImageAlphaNoneSkipFirst的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆