Objective c 如何在Cocoa-C中将文本转换为图像

Objective c 如何在Cocoa-C中将文本转换为图像,objective-c,cocoa,Objective C,Cocoa,我正在寻找一种将一段文本转换为Cocoa中的图像的方法。一切似乎都在描述如何将图像转换为文本,而不是将文本转换为图像 简单地说,我想取一个单词(比如“Kevin”)并将其转换为位图图像以进行操作并保存为JPEG 给出答案的人太棒了。感谢您提供了三种不同且同样有效的方法(是的,我已经测试过了)…非常酷,我希望我能给您所有正确的答案。我相信您想要的功能是 用法示例: NSString *input = /* ... */; CGContextRef context = /* create a gra

我正在寻找一种将一段文本转换为Cocoa中的图像的方法。一切似乎都在描述如何将图像转换为文本,而不是将文本转换为图像

简单地说,我想取一个单词(比如“Kevin”)并将其转换为位图图像以进行操作并保存为JPEG


给出答案的人太棒了。感谢您提供了三种不同且同样有效的方法(是的,我已经测试过了)…非常酷,我希望我能给您所有正确的答案。

我相信您想要的功能是

用法示例:

NSString *input = /* ... */;
CGContextRef context = /* create a graphics context */;

// make sure you have set up the font
CGContextShowTextAtPoint(context, 5, 5, [input UTF8String], [input length]);

编辑:我误读了这个问题,以为你想要Cocoa touch代码(我把它放在最后,以防你想要)。下面是使用CoreText在Cocoa中实现此功能的一种方法(正如另一张海报所说,有多种方法):

这是cocoa touch版本:

// Figure out the dimensions of the string in a given font.
NSString* kevin = @"Kevin";
UIFont* font = [UIFont systemFontOfSize:12.0f];
CGSize size = [kevin sizeWithFont:font];
// Create a bitmap context into which the text will be rendered.
UIGraphicsBeginImageContext(size);
// Render the text 
[kevin drawAtPoint:CGPointMake(0.0, 0.0) withFont:font];
// Retrieve the image
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
// Convert to JPEG
NSData* data = UIImageJPEGRepresentation(image, 1.0);
// Figure out a safe path
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(
                                    NSDocumentDirectory,
                                    NSUserDomainMask,
                                    YES);
NSString *docDir = [arrayPaths objectAtIndex:0];
// Write the file
NSString *filePath = [docDir stringByAppendingPathComponent:@"Kevin.jpg"];
BOOL success = [data writeToFile:filePath atomically:YES];
if(!success)
{
    NSLog(@"Failed to write to file. Perhaps it already exists?");
}
else
{
    NSLog(@"JPEG file successfully written to %@", filePath);
}
// Clean up
UIGraphicsEndImageContext();
当我开始iOS编程时,我发现以下事情不直观或不寻常。测量和绘制字符串的方法是
NSString
上的方法(与其他系统中的图形上下文不同)。保存数据的方法是
NSData
上的方法,而不是文件类!创建图形上下文的函数是纯C函数,不属于任何类

希望这有帮助

有很多不同的方法可以做到这一点(幸运或不幸)

第1版:仅适用于AppKit/Foundation

NSString *text = ...;
NSDictionary *attr = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSFont fontWithName:@"Helvetica" size:24], NSFontAttributeName,
    nil];
NSImage *img = [[NSImage alloc] initWithSize:NSMakeSize(250, 250)];
[img lockFocus];
[text drawAtPoint:NSMakePoint(10, 10) withAttributes:attr];
[img unlockFocus];

// when you want to write it to a JPEG
NSData *dat = [NSBitmapImageRep
    representationOfImageRepsInArray:[img representations]
    usingType:NSJPEGFileType
    properties:[NSDictionary dictionaryWithObjectsAndKeys:
        [NSNumber numberWithFloat:0.9], NSImageCompressionFactor,
        nil]];
然后,您可以将
dat
写入您认为合适的文件

第2版:

同样可以使用
CGContextRef
(创建位图上下文)和等效的Quartz API实现。这样就不需要使用Objective C,但是代码会因此稍微长一点。您还可以使用Quartz(
CGxxx
)和AppKit(
NSxxx
)API的各种混合,但Quartz API通常使用起来更麻烦(因为它们的灵活性、工作分配和其他问题)

第3版:

您还可以使用Quartz+核心文本,即OS X 10.5+。这允许您在文本的精确布局方面具有很大的灵活性,并且还提供了一种相对简单的方法,可以在将文本绘制到位图之前测量文本的大小(因此可以使位图足够大)


脚注:在绘制文本之前,像“倾斜”这样的东西很容易应用。可以使用skew绘制文本(请参见
nsaffinettransform
和)。

这里有一个最小的命令行工具,它可以实现您所描述的功能。将要保存结果的路径传递给它,例如:

/test foo.tiff

#导入
int main(int argc,const char*argv[]
{
@自动释放池{
NSString*string=@“你好,世界!”;
NSString*path=[[NSProcessInfo processInfo]参数]对象索引:1];
NSDictionary*属性=
@{NSFontAttributeName:[NSFont fontWithName:@“Helvetica”大小:40.0],
NSForegroundColorAttributeName:NSColor.blackColor};
NSImage*image=[[NSImage alloc]initWithSize:[字符串大小属性:属性]];
[图像锁定焦点];
[字符串drawAtPoint:NSZeroPoint with attributes:attributes];
[图像解锁焦点];
[[image TIFFRepresentation]writeToFile:原子路径:是];
}
返回0;
}

这是否允许我将其保存为图像?通常,您应该使用更高级别的API,因为CGContextShowTextAtPoint()有许多众所周知的缺陷,而且,不需要降低到CG级别。NSString和NSAttributedString都有绘图方法。我该死的是,NSResponder是对的。但是,你仍然需要一个上下文来绘制它。绘制它的最简单方法是创建一个NSImage实例。如果这是针对iPhone,那就太好了,但最初的问题被标记为cocoa,而不是cocoa touch。尽管这三个都是很好的例子,尽管我相信有更简单的方法来编写它,但这本书还是把它放在了新手的复制粘贴级别上。这并没有产生一个精确的边界框。例如,尝试
y
,您会发现顶部的空间太大。如果您想要精确的边界框,请使用
CTLineGetImageBounds
查看:@hypercrypt invalid edit。这是关于可可粉的,不是可可粉。回滚。作为一个在Cocoa和Windows GDI中都做过文本的人,我不得不说,Windows GDI方法(
ScriptItemize
->
ScriptShape
->
ScriptPlace
->等)需要大约3倍于Cocoa中相同功能的代码。(GDI并不是最新的API,但仍然是。)实际上,使用C#只需创建一个位图,位图对象就具有在x,y坐标处写入文本的内置功能。它非常简单。下面是代码C#Style Bitmap myBitmap=new Bitmap(“C:\\myImage.jpg”);Graphics g=Graphics.FromImage(myBitmap);g、 抽绳(“My\nText”,新字体(“Tahoma”,40),画笔。白色,新点F(0,0))@Richard J.Ross III我的错,在我编辑时它被标记为iOS…不幸的是,我不知道命令行和窗口程序之间是否有区别,因为我再次来自一个m$世界,但这似乎编译得很好,但抛出了一个上下文错误。这应该被认为是正确的答案。
NSString *text = ...;
NSDictionary *attr = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSFont fontWithName:@"Helvetica" size:24], NSFontAttributeName,
    nil];
NSImage *img = [[NSImage alloc] initWithSize:NSMakeSize(250, 250)];
[img lockFocus];
[text drawAtPoint:NSMakePoint(10, 10) withAttributes:attr];
[img unlockFocus];

// when you want to write it to a JPEG
NSData *dat = [NSBitmapImageRep
    representationOfImageRepsInArray:[img representations]
    usingType:NSJPEGFileType
    properties:[NSDictionary dictionaryWithObjectsAndKeys:
        [NSNumber numberWithFloat:0.9], NSImageCompressionFactor,
        nil]];
#import <Cocoa/Cocoa.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {
      NSString *string = @"Hello, World!";
      NSString *path = [[[NSProcessInfo processInfo] arguments] objectAtIndex:1];

      NSDictionary *attributes =
        @{ NSFontAttributeName : [NSFont fontWithName:@"Helvetica" size:40.0],
        NSForegroundColorAttributeName : NSColor.blackColor};

      NSImage *image = [[NSImage alloc] initWithSize:[string sizeWithAttributes:attributes]];
      [image lockFocus];
      [string drawAtPoint:NSZeroPoint withAttributes:attributes];
      [image unlockFocus];
      [[image TIFFRepresentation] writeToFile:path atomically:YES];
    }
    return 0;
}