You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS Objective-C中二维码矢量NSImage导出及CGPDFContextCreate使用问题

Hey there! Let's work through how to get a vector-format QR code instead of a bitmap in your project. The core issue is that CGBitmapContextCreateImage only works with bitmap contexts—since you're switching to a CGPDFContext (a vector context), we need to adjust how we capture the final output.

Key Changes to Your Code

Instead of generating a CGImage from the context, we'll leverage the PDF data produced by CGPDFContext, which retains vector information. Here's the revised full function, with explanations of critical adjustments:

+ (NSImage *)vectorQRImageForString:(NSString *)string imageSize:(CGFloat)size {
    if (![string length]) {
        return nil;
    }
    int str1;
    QRcode *code = QRcode_encodeString([string UTF8String], 0, str1, QR_MODE_8, 1);
    if (!code) {
        return nil;
    }

    // Prepare a data container to hold the PDF output
    NSMutableData* outputData = [[NSMutableData alloc] init];
    CGDataConsumerRef dataConsumer = CGDataConsumerCreateWithCFData((CFMutableDataRef)outputData);
    if (!dataConsumer) {
        QRcode_free(code);
        return nil;
    }

    // Create a vector-based PDF context instead of a bitmap context
    CGRect rect = CGRectMake(0.0, 0.0, size, size);
    CGContextRef ctx = CGPDFContextCreate(dataConsumer, &rect, NULL);
    if (!ctx) {
        CGDataConsumerRelease(dataConsumer);
        QRcode_free(code);
        return nil;
    }

    // Start a new PDF page
    CGPDFContextBeginPage(ctx, NULL);

    // Adjust coordinate system to match your original bitmap context (top-left origin)
    // PDF contexts default to bottom-left origin, so we flip and translate to align
    CGAffineTransform flipTransform = CGAffineTransformMakeScale(1, -1);
    CGAffineTransform translateTransform = CGAffineTransformMakeTranslation(0, -size);
    CGContextConcatCTM(ctx, CGAffineTransformConcat(flipTransform, translateTransform));

    // Draw the QR code as vector shapes (critical: ensure your drawQRCode method uses vector drawing!)
    [MainClass drawQRCode:code context:ctx size:size];

    // Finalize the PDF page and clean up context resources
    CGPDFContextEndPage(ctx);
    CGContextRelease(ctx);
    CGDataConsumerRelease(dataConsumer);

    // Create an NSImage from the PDF data (this retains vector properties)
    NSImage *qrImage = [[NSImage alloc] initWithData:outputData];
    qrImage.size = NSMakeSize(size, size);

    QRcode_free(code);
    return qrImage;
}

Critical Notes for Success

  1. Ensure drawQRCode: uses vector drawing
    Your existing drawQRCode method must draw vector shapes (like rectangles) instead of manipulating bitmap pixels. If it's currently writing directly to bitmap data, rewrite it to use CGContextFillRect for each QR cell. For example:

    + (void)drawQRCode:(QRcode *)code context:(CGContextRef)ctx size:(CGFloat)size {
        if (!code || !ctx) return;
    
        CGFloat cellSize = size / code->width;
        CGContextSetFillColorWithColor(ctx, [NSColor blackColor].CGColor);
    
        for (int y = 0; y < code->width; y++) {
            for (int x = 0; x < code->width; x++) {
                unsigned char cell = code->data[y * code->width + x];
                if (cell & 0x01) {
                    CGRect cellRect = CGRectMake(x * cellSize, y * cellSize, cellSize, cellSize);
                    CGContextFillRect(ctx, cellRect);
                }
            }
        }
    }
    
  2. Direct PDF export (optional)
    If you don't need an NSImage and just want to save the vector QR code as a PDF file, skip creating the NSImage and write the outputData directly:

    [outputData writeToFile:@"/your/path/qrcode.pdf" atomically:YES];
    
  3. Coordinate system alignment
    The flip/translate transform ensures your QR code isn't drawn upside-down, matching the output of your original bitmap context.

内容的提问来源于stack exchange,提问作者GeraldTheGerm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 00:22:31