Test Failed
Push — resize ( fbaf05...026e01 )
by Mikael
02:27
created

CAsciiArt   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 207
Duplicated Lines 2.9 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 6
loc 207
rs 10
c 0
b 0
f 0
ccs 0
cts 71
cp 0
wmc 16
lcom 1
cbo 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A addCharacterSet() 0 5 1
A setOptions() 0 22 2
A createFromFile() 0 21 3
A luminanceAreaAverage() 0 17 3
B getLuminance() 6 19 5
A luminance2character() 0 6 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Mos\CImage;
4
5
/**
6
 * Create an ASCII version of an image.
7
 *
8
 */
9
class CAsciiArt
10
{
11
    /**
12
     * Character set to use.
13
     */
14
    private $characterSet = array(
15
        'one' => "#0XT|:,.' ",
16
        'two' => "@%#*+=-:. ",
17
        'three' => "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
18
    );
19
20
21
22
    /**
23
     * Current character set.
24
     */
25
    private $characters = null;
26
27
28
29
    /**
30
     * Length of current character set.
31
     */
32
    private $charCount = null;
33
34
35
36
    /**
37
     * Scale of the area to swap to a character.
38
     */
39
    private $scale = null;
40
41
42
43
    /**
44
     * Strategy to calculate luminance.
45
     */
46
    private $luminanceStrategy = null;
47
48
49
50
    /**
51
     * Constructor which sets default options.
52
     */
53
    public function __construct()
54
    {
55
        $this->setOptions();
56
    }
57
58
59
60
    /**
61
     * Add a custom character set.
62
     *
63
     * @param string $key   for the character set.
64
     * @param string $value for the character set.
65
     *
66
     * @return $this
67
     */
68
    public function addCharacterSet($key, $value)
69
    {
70
        $this->characterSet[$key] = $value;
71
        return $this;
72
    }
73
74
75
76
    /**
77
     * Set options for processing, defaults are available.
78
     *
79
     * @param array $options to use as default settings.
80
     *
81
     * @return $this
82
     */
83
    public function setOptions($options = array())
84
    {
85
        $default = array(
86
            "characterSet" => 'two',
87
            "scale" => 14,
88
            "luminanceStrategy" => 3,
89
            "customCharacterSet" => null,
90
        );
91
        $default = array_merge($default, $options);
92
        
93
        if (!is_null($default['customCharacterSet'])) {
94
            $this->addCharacterSet('custom', $default['customCharacterSet']);
95
            $default['characterSet'] = 'custom';
96
        }
97
        
98
        $this->scale = $default['scale'];
99
        $this->characters = $this->characterSet[$default['characterSet']];
100
        $this->charCount = strlen($this->characters);
101
        $this->luminanceStrategy = $default['luminanceStrategy'];
102
        
103
        return $this;
104
    }
105
106
107
108
    /**
109
     * Create an Ascii image from an image file.
110
     *
111
     * @param string $filename of the image to use.
112
     *
113
     * @return string $ascii with the ASCII image.
114
     */
115
    public function createFromFile($filename)
116
    {
117
        $img = imagecreatefromstring(file_get_contents($filename));
118
        list($width, $height) = getimagesize($filename);
119
120
        $ascii = null;
121
        $incY = $this->scale;
122
        $incX = $this->scale / 2;
123
        
124
        for ($y = 0; $y < $height - 1; $y += $incY) {
125
            for ($x = 0; $x < $width - 1; $x += $incX) {
126
                $toX = min($x + $this->scale / 2, $width - 1);
127
                $toY = min($y + $this->scale, $height - 1);
128
                $luminance = $this->luminanceAreaAverage($img, $x, $y, $toX, $toY);
0 ignored issues
show
Documentation introduced by
$img is of type resource, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
129
                $ascii .= $this->luminance2character($luminance);
130
            }
131
            $ascii .= PHP_EOL;
132
        }
133
134
        return $ascii;
135
    }
136
137
138
139
    /**
140
     * Get the luminance from a region of an image using average color value.
141
     *
142
     * @param string  $img the image.
143
     * @param integer $x1  the area to get pixels from.
144
     * @param integer $y1  the area to get pixels from.
145
     * @param integer $x2  the area to get pixels from.
146
     * @param integer $y2  the area to get pixels from.
147
     *
148
     * @return integer $luminance with a value between 0 and 100.
149
     */
150
    public function luminanceAreaAverage($img, $x1, $y1, $x2, $y2)
151
    {
152
        $numPixels = ($x2 - $x1 + 1) * ($y2 - $y1 + 1);
153
        $luminance = 0;
154
        
155
        for ($x = $x1; $x <= $x2; $x++) {
156
            for ($y = $y1; $y <= $y2; $y++) {
157
                $rgb   = imagecolorat($img, $x, $y);
158
                $red   = (($rgb >> 16) & 0xFF);
159
                $green = (($rgb >> 8) & 0xFF);
160
                $blue  = ($rgb & 0xFF);
161
                $luminance += $this->getLuminance($red, $green, $blue);
162
            }
163
        }
164
        
165
        return $luminance / $numPixels;
166
    }
167
168
169
170
    /**
171
     * Calculate luminance value with different strategies.
172
     *
173
     * @param integer $red   The color red.
174
     * @param integer $green The color green.
175
     * @param integer $blue  The color blue.
176
     *
177
     * @return float $luminance with a value between 0 and 1.
178
     */
179
    public function getLuminance($red, $green, $blue)
180
    {
181
        switch ($this->luminanceStrategy) {
182 View Code Duplication
            case 1:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
183
                $luminance = ($red * 0.2126 + $green * 0.7152 + $blue * 0.0722) / 255;
184
                break;
185 View Code Duplication
            case 2:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
186
                $luminance = ($red * 0.299 + $green * 0.587 + $blue * 0.114) / 255;
187
                break;
188
            case 3:
189
                $luminance = sqrt(0.299 * pow($red, 2) + 0.587 * pow($green, 2) + 0.114 * pow($blue, 2)) / 255;
190
                break;
191
            case 0:
192
            default:
193
                $luminance = ($red + $green + $blue) / (255 * 3);
194
        }
195
196
        return $luminance;
197
    }
198
199
200
201
    /**
202
     * Translate the luminance value to a character.
203
     *
204
     * @param string $position a value between 0-100 representing the
0 ignored issues
show
Bug introduced by
There is no parameter named $position. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
205
     *                         luminance.
206
     *
207
     * @return string with the ascii character.
208
     */
209
    public function luminance2character($luminance)
210
    {
211
        $position = (int) round($luminance * ($this->charCount - 1));
212
        $char = $this->characters[$position];
213
        return $char;
214
    }
215
}
216