Skip to content

Commit a70ee61

Browse files
authored
Adjust the api (#12)
1 parent 3e6fc17 commit a70ee61

File tree

15 files changed

+183
-97
lines changed

15 files changed

+183
-97
lines changed

README.md

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,31 @@
22

33
You can add an artistic touch to your console.
44

5-
## Usage
5+
To use embroidery, add the following line in your `build.sbt` file:
6+
```
7+
libraryDependencies += "com.github.wi101" %% "embroidery" % "0.1.1"
8+
```
69

7-
This is an example usage:
10+
## Usage
811

912
1. Convert your text to ASCII Art:
1013
`title.asciiArt` returns a String that you can display or use in your project.
14+
Or you can use the syntax `title.toAsciiArt`.
1115

1216
```scala
13-
import embroidery.asciiArt.title
17+
import embroidery.title
1418

1519
title.asciiArt("Hello world")
1620
```
1721

22+
Or:
23+
24+
```scala
25+
import embroidery._
26+
27+
"Hello".toAsciiArt
28+
```
29+
1830
Output:
1931

2032
```
@@ -32,11 +44,16 @@ Output:
3244
You can specify the spaces between the character.
3345
For example, if you would like to display S c a l a, you can call:
3446
```scala
35-
import embroidery.asciiArt._
47+
import embroidery.title
3648

3749
title.asciiArt("Scala", art = 'S', spaces = 1)
3850
```
51+
Or
52+
```scala
53+
import embroidery._
3954

55+
"Scala".toAsciiArt(art = 'S', spaces = 1)
56+
```
4057
Output:
4158

4259
```
@@ -57,42 +74,72 @@ WARNNG: The title should be short to be able to display it in your screen (maxim
5774
2. Convert your LOGO to ASCII Art:
5875

5976
You can get the Ascii Art of your icons using `logo.asciiArt` method.
77+
Or you can use the syntax `logoPath.toAsciiArt`.
78+
79+
```scala
80+
import embroidery.logo
6081

61-
```
6282
logo.asciiArt("src/test/scala/embroidery/asciiArt/logos/images/pikachu.png")
6383
```
84+
85+
OR
86+
87+
```scala
88+
import embroidery._
89+
90+
ImagePath("src/test/scala/embroidery/asciiArt/logos/images/pikachu.png").toAsciiArt
91+
```
6492
| pikachu.png | result with ASCII Art |
6593
| --- | --- |
6694
| ![pikachu](https://user-images.githubusercontent.com/3535357/87250424-f0908c00-c464-11ea-9bb9-bc92b23ca63d.png) | ![pikachu](https://user-images.githubusercontent.com/3535357/87250405-d48cea80-c464-11ea-9ccc-ce13d4ef60dd.png) |
6795

68-
```
96+
```scala
97+
import embroidery.logo
98+
6999
logo.asciiArt("src/test/scala/embroidery/asciiArt/logos/images/zio.png")
70100
```
101+
102+
OR
103+
104+
```scala
105+
import embroidery._
106+
107+
ImagePath("src/test/scala/embroidery/asciiArt/logos/images/zio.png").toAsciiArt
108+
```
109+
71110
| zio.png | result with ASCII Art |
72111
| --- | --- |
73112
| ![zio](https://user-images.githubusercontent.com/3535357/87250611-49145900-c466-11ea-8f75-ccfacc4bae05.png) | ![zio](https://user-images.githubusercontent.com/3535357/87250628-7234e980-c466-11ea-87c1-ae82c09703ce.png) |
74113

75-
```
114+
```scala
115+
import embroidery.logo
116+
76117
logo.asciiArt("src/test/scala/embroidery/asciiArt/logos/images/scala.jpg")
77118
```
119+
120+
OR
121+
122+
```scala
123+
import embroidery._
124+
125+
ImagePath("src/test/scala/embroidery/asciiArt/logos/images/scala.jpg").toAsciiArt
126+
```
127+
78128
| scala.jpg | result with ASCII Art |
79129
| --- | --- |
80130
|![scala](https://user-images.githubusercontent.com/3535357/36055500-2611c978-0dfd-11e8-8ca4-15c689fa0438.jpg) | ![scala](https://user-images.githubusercontent.com/3535357/87250678-d8ba0780-c466-11ea-9e4d-bd1b7de03119.png) |
81131

82132
You can also decide which characters to use on each brightness level:
83133

84134
```scala
85-
import embroidery.asciiArt._
135+
import embroidery._
86136

87137
val pixelsWithArt: List[PixelAsciiArt] = List(
88138
PixelAsciiArt(Pixel(255), Art(' ')),
89139
PixelAsciiArt(Pixel(0), Art('#'))
90140
)
91141

92-
val img: String = logo.asciiArt(
93-
"src/test/scala/embroidery/asciiArt/images/zio.png",
94-
pixelsWithArt
95-
)
142+
val img: String = ImagePath("src/test/scala/embroidery/asciiArt/images/zio.png").toAsciiArt(pixelsWithArt)
96143
val s = img.flatMap(
97144
c =>
98145
if (c != ' ' && c != '\n')
@@ -109,7 +156,8 @@ Output:
109156
You can also control the size of your logo:
110157

111158
```scala
112-
import embroidery.asciiArt._
159+
import embroidery._
160+
113161
val pixelsWithArt: List[PixelAsciiArt] = List(
114162
PixelAsciiArt(Pixel(255), Art(' ')),
115163
PixelAsciiArt(Pixel(230), Art('.')),
@@ -134,6 +182,7 @@ import embroidery.asciiArt._
134182
100,
135183
50
136184
)
185+
// The same as: ImagePath("...").toAsciiArt(pixelsWithArt, 100, 50)
137186
val scala = img.flatMap(
138187
c =>
139188
if (c != ' ' && c != '\n')

src/main/scala/embroidery/asciiArt/Embroidery.scala renamed to src/main/scala/embroidery/Embroidery.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package embroidery.asciiArt
1+
package embroidery
22

33
import java.awt.Color
44
import java.awt.image.BufferedImage
@@ -44,7 +44,7 @@ abstract class Embroidery { self =>
4444
Try {
4545
val matrix = toPixelMatrix
4646
matrix.pixels.foldLeft("") { (asciiArt, lines) =>
47-
asciiArt + lines.map(getAsciiArt).mkString + "\n"
47+
asciiArt + lines.map(getAsciiArt).mkString + System.getProperty("line.separator")
4848
}
4949
}.recover { case err => s"$RED<error>$RESET Input couldn't be converted to ASCII Art. Reason: $err." }
5050
.getOrElse(s"$RED<error>$RESET Unexpected error!")

src/main/scala/embroidery/asciiArt/logo/package.scala

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/main/scala/embroidery/asciiArt/title/package.scala

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/main/scala/embroidery/asciiArt/logo/LogoArt.scala renamed to src/main/scala/embroidery/logo/LogoArt.scala

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
package embroidery
2-
package asciiArt
3-
package logo
1+
package embroidery.logo
42

53
import java.awt.Image
64
import java.awt.image.BufferedImage
75
import java.io.{ File, IOException }
86
import javax.imageio.ImageIO
97

10-
final case class LogoArt private (logo: BufferedImage, url: URL, logoStyle: LogoStyle) extends Embroidery {
8+
import embroidery.{ Embroidery, Pixel }
9+
10+
final case class LogoArt private (logo: BufferedImage, url: LogoPath, logoStyle: LogoStyle) extends Embroidery {
1111

1212
override def drawImage(): BufferedImage = {
1313
val (width, height) =
@@ -51,17 +51,24 @@ object LogoArt {
5151
def apply(imgPath: String, maybeLogoStyle: Either[String, LogoStyle]): Embroidery = {
5252
val result = for {
5353
logoStyle <- maybeLogoStyle
54-
url <- URL(imgPath)
55-
logo <- readLogo(url)
54+
url = LogoPath(imgPath)
55+
logo <- readLogo(url)
5656
} yield LogoArt(logo, url, logoStyle)
5757
result.fold(Embroidery.Empty, identity)
5858
}
5959

60-
private def readLogo(url: URL): Either[String, BufferedImage] =
60+
private def readLogo(url: LogoPath): Either[String, BufferedImage] =
6161
try {
62-
val bufferedImage = ImageIO.read(new File(url.value))
63-
if (bufferedImage.getWidth == 0 || bufferedImage.getHeight == 0) Left("Width and Height should be > 0")
64-
else Right(bufferedImage)
62+
def isValid: Boolean = {
63+
val regex = "[^\\s]+(\\.(?i)(jpg|jpeg|png|bmp))$"
64+
url.value.matches(regex)
65+
}
66+
if (isValid) {
67+
val bufferedImage = ImageIO.read(new File(url.value))
68+
if (bufferedImage.getWidth == 0 || bufferedImage.getHeight == 0) Left("Width and Height should be > 0")
69+
else Right(bufferedImage)
70+
} else
71+
Left(s"Invalid path: $url, Embroidery supports only: jpg, jpeg, png, bmp formats.")
6572
} catch {
6673
case ex: IOException => Left(ex.getMessage)
6774
}

src/main/scala/embroidery/asciiArt/logo/model.scala renamed to src/main/scala/embroidery/logo/model.scala

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,8 @@
1-
package embroidery.asciiArt
1+
package embroidery
22
package logo
33

4-
final case class URL private (value: String) extends AnyVal {
5-
def isValid: Boolean = {
6-
val regex = "[^\\s]+(\\.(?i)(jpg|jpeg|png|bmp))$"
7-
value.matches(regex)
8-
}
9-
}
10-
11-
object URL {
12-
def apply(path: String): Either[String, URL] = {
13-
val url = new URL(path)
14-
if (url.isValid) Right(url)
15-
else Left(s"Invalid path: $path, Embroidery supports only: jpg, jpeg, png, bmp formats.")
16-
}
4+
final case class LogoPath(value: String) {
5+
override def toString: String = value
176
}
187

198
// Logo
@@ -24,20 +13,21 @@ final case class Size(width: Int, height: Int) {
2413
}
2514

2615
final case class LogoStyle private (
27-
pixelsWithArt: List[PixelAsciiArt] = PixelAsciiArt.pixelsWithArt,
28-
maxSize: Size = Size(100, 100)
16+
pixelsWithArt: List[PixelAsciiArt],
17+
maxSize: Size
2918
) {
3019
def isValid: Boolean = maxSize.width > 10 || maxSize.height > 10
3120
val darkestArt: Art =
3221
pixelsWithArt.lastOption.map(_.art).getOrElse(Art('#'))
3322
}
3423

3524
object LogoStyle {
36-
val default: Either[String, LogoStyle] = Right(new LogoStyle(PixelAsciiArt.pixelsWithArt))
3725
val MinSize = Size(20, 20)
26+
val defaultSize = Size(100, 100)
27+
val default: Either[String, LogoStyle] = Right(new LogoStyle(PixelAsciiArt.pixelsWithArt, defaultSize))
3828
def apply(
3929
pixelsWithArt: List[PixelAsciiArt] = PixelAsciiArt.pixelsWithArt,
40-
maxSize: Size = Size(100, 100)
30+
maxSize: Size = defaultSize
4131
): Either[String, LogoStyle] = {
4232
if (maxSize.width >= MinSize.width || maxSize.height >= MinSize.height) Right(new LogoStyle(pixelsWithArt, maxSize))
4333
else Left(s"$maxSize is invalid, it should be at least $MinSize")
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package embroidery
2+
3+
package object logo {
4+
5+
def asciiArt(path: String): String =
6+
LogoArt(path, LogoStyle.default).toAsciiArt
7+
8+
def asciiArt(path: String, pixelsWithArt: List[PixelAsciiArt]): String =
9+
LogoArt(path, LogoStyle(pixelsWithArt)).toAsciiArt
10+
11+
def asciiArt(path: String, width: Int, height: Int): String =
12+
LogoArt(path, LogoStyle(maxSize = Size(width, height))).toAsciiArt
13+
14+
def asciiArt(path: String, pixelsWithArt: List[PixelAsciiArt], width: Int, height: Int): String =
15+
LogoArt(path, LogoStyle(pixelsWithArt, Size(width, height))).toAsciiArt
16+
}

src/main/scala/embroidery/asciiArt/model.scala renamed to src/main/scala/embroidery/model.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package embroidery.asciiArt
1+
package embroidery
22

33
// Common Data types
44
final case class Art(value: Char) extends AnyVal
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package object embroidery {
2+
3+
/**
4+
* Apply asciiArt to any string
5+
*/
6+
implicit class TitleHelper(val text: String) extends AnyVal {
7+
def toAsciiArt: String =
8+
title.asciiArt(text)
9+
10+
def toAsciiArt(art: Char): String =
11+
title.asciiArt(text, art = art)
12+
13+
def toAsciiArt(art: Char, spaces: Int): String =
14+
title.asciiArt(text, art = art, spaces = spaces)
15+
16+
def toAsciiArt(spaces: Int): String =
17+
title.asciiArt(text, spaces = spaces)
18+
}
19+
20+
/**
21+
* Apply asciiArt to any image path.
22+
* @example
23+
* ImagePath("src/img/logo.png").toAsciiArt
24+
*/
25+
type ImagePath = logo.LogoPath
26+
type PixelAsciiArt = logo.PixelAsciiArt
27+
val ImagePath: logo.LogoPath.type = logo.LogoPath
28+
val PixelAsciiArt: logo.PixelAsciiArt.type = logo.PixelAsciiArt
29+
30+
implicit class LogoHelper(val path: ImagePath) extends AnyVal {
31+
def toAsciiArt: String =
32+
logo.asciiArt(path.value)
33+
34+
def toAsciiArt(pixelsWithArt: List[PixelAsciiArt]): String =
35+
logo.asciiArt(path.value, pixelsWithArt)
36+
37+
def toAsciiArt(width: Int, height: Int): String =
38+
logo.asciiArt(path.value, width, height)
39+
40+
def toAsciiArt(pixelsWithArt: List[PixelAsciiArt], width: Int, height: Int): String =
41+
logo.asciiArt(path.value, pixelsWithArt, width, height)
42+
}
43+
44+
}

src/main/scala/embroidery/asciiArt/title/TitleArt.scala renamed to src/main/scala/embroidery/title/TitleArt.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package embroidery.asciiArt
1+
package embroidery
22
package title
33

44
import java.awt.Font
@@ -33,6 +33,6 @@ final case class TitleArt private (title: Title) extends Embroidery {
3333
}
3434

3535
object TitleArt {
36-
def apply(value: String, style: TitleStyle): Embroidery =
36+
def apply(value: String, style: TitleStyle = TitleStyle.default): Embroidery =
3737
Title(value, style).fold[Embroidery](Embroidery.Empty, TitleArt(_))
3838
}

0 commit comments

Comments
 (0)