微信号:SwiftDev

介绍:探讨移动开发技术,推荐常用框架,分享移动互联网资讯. 主要提供Swift;IOS等相关技术资讯

Swift 实现图片转字符画的功能

2015-06-26 12:51 Swift开发

This article explores an iOS app, written in a functional Swift style, that converts an image to ASCII art. For example, when given the famous Lenna photograph…

…it creates a string that, when printed, looks something like this…

Zooming into her lovely face reveals that the image is actually text!

The Xcode project is available at https://github.com/ijoshsmith/swift-ascii-art
The big picture
Each pixel in an image is mapped to an ASCII value, referred to here as a symbol.

An image’s pixels are first transformed to an intermediary value, as seen below:

Let’s take this step-by-step.
First a pixel’s color is converted to a grayscale color. The grayscale color’s intensity (i.e. brightness) is normalized to a value between 0 and 1, where black is 0 and white is 1.
The next step is, to me, the most interesting part of the algorithm. Each color intensity value is translated to an ASCII symbol. Later we will visit the AsciiPalette class, which supports that.
Lastly, rows of ASCII symbols are joined to form a giant, multi-line string: the ASCII art.
Algorithm implementation
AsciiArtist implements the three steps outlined above; as seen on lines 31 to 33.

An AsciiArtist object relies on Pixel and AsciiPalette, which we’ll look at next.
Transforming pixels to intensities
Pixel represents the color at a specific image coordinate. A color consists of four bytes; one byte per channel (red, green, blue, and alpha). AsciiArtist asks a Pixel to determine its color intensity, which, as previously mentioned, is calculated by normalizing the pixel’s grayscale value to a percentage. Let’s see how that works…

In case you’re wondering about those weight values on lines 47 to 49, they are industry-standard numbers used for grayscale conversion, as explained here.
Transforming intensities to symbols
The symbolFromIntensity function in AsciiArtist transforms a color intensity to an ASCII symbol, by converting a normalized intensity value to an array index. That array is provided by AsciiPalette. The first symbol in the array is used for very dark pixels and the last symbol is for very bright pixels. Here is that AsciiArtist function again, for easy reference:

The question is: which ASCII symbols should be in the array, and in what order?
A poorly designed symbol palette yields improperly shaded ASCII art:

A better symbol palette produces a vastly superior result:

My approach to designing a good symbol palette is to let the computer figure it out. The AsciiPalette class renders each symbol to a separate image, with black text on a white background. It then sorts the symbols by the number of white pixels in their images. The more white pixels in the image, the higher the symbol’s intensity. The blank space character (‘ ‘) has the highest intensity value since it contains only white pixels, and would therefore be the last symbol in the array.

The AsciiPalette designated initializer requires a UIFont argument because the choice of font affects how a character is rendered, impacting the number of white pixels around it.
The code in this article is available at https://github.com/ijoshsmith/swift-ascii-art

原文地址:http://ijoshsmith.com/2015/04/29/creating-ascii-art-in-functional-swift/


欢迎关注我的微信公众号,分享Swift开发,IOS开发和互联网内容

微信号:Swift开发


 
Swift开发 更多文章 协同写作的力量——中国开发者9天完成《Swift语言》中文版 程序员眼中的苹果Swift语言:简单 易学 高效 使用Dollar.$wift简化代码编写 Swift版知乎日报 Swift-PM25 一个基于Swift实现的PM2.5查询示例
猜您喜欢 教孩子编程的 6 个小建议 什么是 Code Golf 如果你忙的没时间看这篇文章,你应该把这篇文章看两遍 CSharp的四个基本技巧 2014年互联网败局大起底