ASCIImage 1.0.0

ASCIImage 1.0.0

测试已测试
Lang语言 Obj-CObjective C
许可证 MIT
发布上次发布2015年5月

Charles Parnot 维护。



ASCIImage 1.0.0

从 NSString 创建 UIImage / NSImage 实例,通过结合 ASCII 艺术和幼儿园技能。

有用的链接

常见问题

为什么选择 ASCIImage?

原始博客帖子解释了 ASCIImage 的起源,但它可能仍然令人困惑:为什么有人会使用它,以及用于什么样的目的。它的主要优势是结合了两件事:(1)直接在代码中拥有图像,并且(2)看到图像。代码就是图像,图像就是代码。实际上,它只能以这种方式工作对于由几行和/或简单形状组成的简单图像。任何更复杂的东西都会破坏第(2)点,并且可能根本无法使用 ASWIImage 故意限制的选项来实现。

像素还是向量?

虽然最初它是基于位图开发的,而 ASCII 表示看起来像像素,但由于数字连接的方法,它实际上是一个向量绘图工具,具有强制像素对齐。这可能有点令人困惑。即使我没有意识到这一点,我也感到困惑:在我的原始博客帖子中,我一次也没有使用过“向量”一词。只有当第一个编辑器被开发出来(ASWIImage Super Studio)时,我才意识到它可以绘制非常大的图像,并以我从未想象过的方式输出东西。这是因为背后,形状首先被制作成 NSBezierPath。当然,最后,屏幕上的所有内容最终都会变成像素。

接下来是什么?

这个想法和初始实现基本上是一个一天的临时解决方案。但在我之后的一年里,我对一些细节进行了微调,并于2015年3月最终公开。由于这些小改动,它真的满足了我用它所需的所有需求。我可能还会向基于块的API中的绘图“上下文”添加更多选项,特别是为了更好地利用矢量方面,增加缩放和平滑选项。我也很想知道其他人会如何使用它。但我认为我想要尽可能地保持简单,并将其限制在原始精神:代码和图像在一个地方,实现即得满足。对于更复杂的事物,应该使用设计师、真正的图像编辑器和真正的格式。

哪些应用程序正在使用 ASCIImage?

如果您在发布的应用程序中使用了 ASCIImage,请让我知道,并将它添加到这里的列表中。

目前,我只知道 Findings (免责声明:作为 ASCIImage 的作者,我通过 Findings 谋生)。

为什么不直接使用 SVG 呢?

唉。

文档

安装

ASCIImage 通过 CocoaPods 提供。要安装它,只需将以下行添加到您的 Podfile 中

pod "ASCIImage"

字符和像素

图像由字符串数组定义,其中每个字符串表示一行。这里有一个例子

NSArray *asciiRepresentation =
@[
@"· · · 1 2 · · · · · ",
@"· · · A # # · · · · ",
@"· · · · # # # · · · ",
@"· · · · · # # # · · ",
@"· · · · · · 9 # 3 · ",
@"· · · · · · 8 # 4 · ",
@"· · · · · # # # · · ",
@"· · · · # # # · · · ",
@"· · · 7 # # · · · · ",
@"· · · 6 5 · · · · · ",
];

在这个文档中,我将只以如下方式表示

· · · 1 2 · · · · · 
· · · A # # · · · · 
· · · · # # # · · · 
· · · · · # # # · · 
· · · · · · 9 # 3 · 
· · · · · · 8 # 4 · 
· · · · · # # # · · 
· · · · # # # · · · 
· · · 7 # # · · · · 
· · · 6 5 · · · · · 

空格被忽略。以下两种表示方法是等价的。很明显,为什么使用额外的空格是建议的:它确实有助于使内容以正确的宽高比显示。

· · · 1 2 · · · · ·          ···12·····
· · · A # # · · · ·          ···A##····
· · · · # # # · · ·          ····###···
· · · · · # # # · ·          ·····###··
· · · · · · 9 # 3 ·          ······9#3·
· · · · · · 8 # 4 ·          ······8#4·
· · · · · # # # · ·          ·····###··
· · · · # # # · · ·          ····###···
· · · 7 # # · · · ·          ···7##····
· · · 6 5 · · · · ·          ···65·····

每一行应该有相同数量的非空白字符,否则您只能看到神秘的控制台日志。以下表示方法是不合法的

! ! I N V A L I D !             N O # G O O D ! 
· ····1 2 · · · · ·               1 2           
· · · A # # · · · ·               A # #         
· · · · # # # · · ·                 # # #       
· · · · · # # # · ·                   # # #     
· · · · · · 9 # 3 ·                     9 # 3   
· · · · · · 8 # 4 ·                     8 # 4   
· · · · · # # # · ·                   # # #     
· · · · # # # · · ·                 # # #       
· · · 7 # # · · · ·               7 # #         
· · · 6 5 · · · · ·               6 5           

特殊字符

虽然所有非空白字符都被视为像素网格的一部分,但大多数字符都是被动的。只有以下字符被视为形状的一部分

1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
Q R S T U V W X Y Z a b c d e f g h i j k l m n p
q r s t u v w x y z

请注意,O(零)和o(小写字母O)被忽略。当前的实现不会忽略大写字母O。这三个中的任何一个都可能被认为是错误,但我认为这是最好的做法。可能我会后悔。很可能不会。

所有其他字符在从字符网格中提取形状时都会被忽略。

以下所有表示方法都是等价的。以下例子中的 '#' 标志对眼睛很有指导作用,我经常使用它们('@' 工作得很好)。但它们也可以被用来恶意隐藏信息!不好!

· 1 2 · · · · ·        · 1 2 · · · · ·         · 1 2 · · · · ·        # 1 2 # # # # # 
· A # # · · · ·        · A @ @ · · · ·         · A · · · · · ·        # A # # # # # # 
· · # # # · · ·        · · @ @ @ · · ·         · · · · · · · ·        # # # # # # # # 
· · · # # # · ·        · · · @ @ @ · ·         · · · · · · · ·        # # # # # # # # 
· · · · 9 # 3 ·        · · · · 9 @ 3 ·         · · · · 9 · 3 ·        # # # # 9 # 3 # 
· · · · 8 # 4 ·        · · · · 8 @ 4 ·         · · · · 8 · 4 ·        # # # # 8 # 4 # 
· · · # # # · ·        · · · @ @ @ · ·         · · · · · · · ·        # # # # # # # # 
· · # # # · · ·        · · @ @ @ · · ·         · · · · · · · ·        # # # # # # # # 
· 7 # # · · · ·        · 7 @ @ · · · ·         · 7 · · · · · ·        # 7 # # # # # # 
· 6 5 · · · · ·        · 6 5 · · · · ·         · 6 5 · · · · ·        # 6 5 # # # # # 

贝塞尔路径

在渲染成 NSImage 之前,ASCII网格被转换成一系列的 NSBezierPath。下面的几节将描述可能创建的不同类型的贝塞尔路径。

多边形

上述字符的最简单用途是使用著名的“连接数字”技术来绘制多边形。每个多边形由一系列连续的字符定义,每当您在上面的列表中跳过一个字符时,就开始新一个多边形。因此,第一个多边形可能由系列 '123456' 定义,下一个形状由 '89ABCDEF' 定义,下一个由 'HIJKLMNOP' 定义等。对于多边形,每个字符只能使用一次(或根本不使用)。如果您用完了字符,您可能正在滥用 ASCIImage!

这里是包含3个多边形的示例,这些多边形使用序列[1,2,3,4,5,6,7,8,9,A]定义,然后是[C,D,E],最后是[G,H,I,J,K,L]。请注意,字符B和F被跳过以区分这三个多边形。旁边的第二个示例与之等价,但最后一个多边形使用序列[a,b,c,d,e,f],没有很好的理由(但也没有坏的理由)。

· · · · · · · · C · · E         · · · · · · · · C · · E 
· · · 1 2 · · · · · · ·         · · · 1 2 · · · · · · · 
· · · A · · · · · · · ·         · · · A · · · · · · · · 
· · · · · · · · · · · D         · · · · · · · · · · · D 
G · H · · · · · · · · ·         a · b · · · · · · · · · 
· · · · · · 9 · 3 · · ·         · · · · · · 9 · 3 · · · 
· · I J · · 8 · 4 · · ·         · · c d · · 8 · 4 · · · 
L · · K · · · · · · · ·         f · · e · · · · · · · · 
· · · · · · · · · · · ·         · · · · · · · · · · · · 
· · · 7 · · · · · · · ·         · · · 7 · · · · · · · · 
· · · 6 5 · · · · · · ·         · · · 6 5 · · · · · · · 
· · · · · · · · · · · ·         · · · · · · · · · · · · 

单个点

当一个多边形仅由一个字符组成时,它将形成一个填充相应点的正方形。以下表示包含了5个单独的点。

· · 1 · · · · · · 5 · T 
· · · · 3 · · · · · · · 
· · · · · · · · · · 7 · 
· · · · · · · · · · · · 

线条

当一个字符恰好被使用两次时,相应的形状将是连接两个点的线条(中心到中心,带有方形的端点,当使用1点宽加粗绘图时,将准确填充像素)。由于此类字符被多次使用,它们不能是多项式的一部分,并且不需要在线条与其他任何形状之间跳过字符。以下是一个包含3条线和三角形的示例。注意,我们没有跳过任何字符(尽管我们可以)。

· · 1 # # # # # # 1 6 · 
· · · · · · · · · · # · 
· · · · 2 · 3 · · · # · 
· · · · · 4 · · · · # · 
· · · · · · · · · · # · 
· · 5 # # # # # # 5 6 · 

椭圆

当一个字符被使用三次或更多次时,相应的形状将是通过包含所有点的最大矩形定义的椭圆。以下所有表示都将产生相同直径为11点的圆。

· · · 1 1 1 1 1 · · ·      · · · · · 1 · · · · ·      · · · · · 1 · · · · ·    
· · 1 · · · · · 1 · ·      · · · · · · · · · · ·      · · · · · · · · · · ·    
· 1 · · · · · · · 1 ·      · · · · · · · · · · ·      · · · · · · · · · · ·    
1 · · · · · · · · · 1      · · · · · · · · · · ·      · · · · · · · · · · ·    
1 · · · · · · · · · 1      · · · · · · · · · · ·      · · · · · · · · · · ·    
1 · · · · · · · · · 1      1 · · · · · · · · · 1      · · · · · · · · · · ·    
1 · · · · · · · · · 1      · · · · · · · · · · ·      · · · · · · · · · · ·    
1 · · · · · · · · · 1      · · · · · · · · · · ·      · · · · · · · · · · ·    
· 1 · · · · · · · 1 ·      · · · · · · · · · · ·      · · · · · · · · · · ·    
· · 1 · · · · · 1 · ·      · · · · · · · · · · ·      · · · · · · · · · · ·    
· · · 1 1 1 1 1 · · ·      · · · · · 1 · · · · ·      1 · · · · · · · · · 1    

API

'API'这个词对于ASCIImage来说有点夸张。它只是一个NSImage类别,包含两个类方法。

我99%的时间使用最简单的方法

+ (PARImage *)imageWithASCIIRepresentation:(NSArray *)rep
                                     color:(PARColor *)color
                           shouldAntialias:(BOOL)shouldAntialias;

使用这种简单形式,单个点、多边形和椭圆将以颜色填充,而线条将以该颜色'加粗'。简单。

第二种方法提供了更高级的选项,可以使用contextHandler块分别设置在每个"形状"上。由块传递的可变字典可以使用以下常量中列出的键进行修改。该字典最初包含ASCIIContextShapeIndex键以指示上下文将应用于哪个形状。

+ (PARImage *)imageWithASCIIRepresentation:(NSArray *)rep
                            contextHandler:(void(^)(NSMutableDictionary *ctx))handler;

以下是字典上下文的键

extern NSString * const ASCIIContextShapeIndex;
extern NSString * const ASCIIContextFillColor;
extern NSString * const ASCIIContextStrokeColor;
extern NSString * const ASCIIContextLineWidth;
extern NSString * const ASCIIContextShouldClose;
extern NSString * const ASCIIContextShouldAntialias;

请注意,这些选项中的某些实际上应用于Bezier路径(线宽、应关闭),而其他一些则应用于实际的图形上下文。反走样选项可以影响两者。ASCIImage在幕后做了一些事情来保持幻象。

作者

cparnot, [email protected]

许可证

ASCIImage可在MIT许可证下使用。更多信息请参阅LICENSE文件。