Completed
Push — master ( 27493f...f3deef )
by Marcin
01:42
created

ElemBitmap   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 36%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 5
dl 0
loc 121
ccs 18
cts 50
cp 0.36
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A getXml() 0 12 1
A getBase64() 0 11 3
B resizeImage() 0 44 5
1
<?php
2
/**
3
 * Grandstream-XMLApp
4
 *
5
 * Copyright (c) 2017 pudelek.org.pl
6
 *
7
 * @license MIT License (MIT)
8
 *
9
 * For the full copyright and license information, please view source file
10
 * that is bundled with this package in the file LICENSE
11
 *
12
 * @author  Marcin Pudełek <[email protected]>
13
 */
14
15
namespace mrcnpdlk\Grandstream\XMLApp\Application\Model\Components;
16
17
18
use mrcnpdlk\Grandstream\XMLApp\Application\ModelInterface;
19
use mrcnpdlk\Grandstream\XMLApp\Exception;
20
use mrcnpdlk\Grandstream\XMLApp\Helper\Rectangle;
21
use mrcnpdlk\Grandstream\XMLApp\MyXML;
22
23
/**
24
 * Class ElemBitmap
25
 *
26
 * This element is to display a bitmap picture on the screen. Inside the <Bitmap> tag of the XML document,
27
 * the picture must be encoded in base64 format already. There are plenty of base64 encoder online
28
 * provided for encoding the .bmp picture. Please make sure the original .bmp picture is in monochrome grey
29
 * level 8 before encoding
30
 *
31
 * <ElemBitmap isfile="true/false" isflash=”true/false”>
32
 * <Bitmap> Bitmap file encoded in base64 format </Bitmap>
33
 * <X> X location </X>
34
 * <Y> Y location </Y>
35
 * </ElemBitmap
36
 *
37
 * @package mrcnpdlk\Grandstream\XMLApp\Application\Model\Components
38
 */
39
class ElemBitmap extends ElemAbstract implements ModelInterface, ElemInterface
40
{
41
    /**
42
     * @var boolean
43
     */
44
    private $isFile;
45
    /**
46
     * @var boolean
47
     */
48
    private $isFlash;
49
    /**
50
     * @var string
51
     */
52
    private $sImgPath;
53
54
    /**
55
     * @var Rectangle
56
     */
57
    private $oCanvas;
58
59
    /**
60
     * ElemBitmap constructor.
61
     *
62
     * @param string                                        $sImgPath
63
     * @param \mrcnpdlk\Grandstream\XMLApp\Helper\Rectangle $oRectangle
64
     *
65
     */
66 1
    public function __construct(string $sImgPath, Rectangle $oRectangle)
67
    {
68 1
        parent::__construct();
69 1
        $this->sImgPath = $sImgPath;
70 1
        $this->oCanvas  = $oRectangle;
71 1
        $this->isFile   = "false";
0 ignored issues
show
Documentation Bug introduced by
The property $isFile was declared of type boolean, but 'false' is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
72 1
        $this->isFlash  = "false";
0 ignored issues
show
Documentation Bug introduced by
The property $isFlash was declared of type boolean, but 'false' is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
73
74 1
    }
75
76
    /**
77
     * @return \mrcnpdlk\Grandstream\XMLApp\MyXML
78
     */
79 1
    function getXml(): MyXML
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
80
    {
81 1
        $oXml = new MyXML('DisplayBitmap');
82
83 1
        $oXml->asObject()->addAttribute('isfile', $this->isFile);
84 1
        $oXml->asObject()->addAttribute('isflash', $this->isFlash);
85 1
        $oXml->asObject()->addChild('X', $this->getPoint()->getX());
86 1
        $oXml->asObject()->addChild('Y', $this->getPoint()->getY());
87 1
        $oXml->asObject()->addChild('Bitmap', $this->getBase64());
88
89 1
        return $oXml;
90
    }
91
92
    /**
93
     * @return string
94
     */
95 1
    private function getBase64()
96
    {
97 1
        if (!extension_loaded('imagick')) {
98 1
            return base64_encode(file_get_contents(__DIR__ . '/../../../img/no_ext.bmp'));
99
        }
100
        try {
101
            return base64_encode($this->resizeImage($this->oCanvas->getWidth(), $this->oCanvas->getHeight())->getImageBlob());
102
        } catch (\Exception $e) {
103
            return base64_encode(file_get_contents(__DIR__ . '/../../../img/no_file.bmp.bmp'));
104
        }
105
    }
106
107
    /**
108
     * @param int      $width
109
     * @param int|null $height
110
     *
111
     * @return \Imagick
112
     * @throws \mrcnpdlk\Grandstream\XMLApp\Exception
113
     */
114
    private function resizeImage(int $width = 100, int $height = null)
115
    {
116
        if (!file_exists($this->sImgPath) || !is_readable($this->sImgPath)) {
117
            throw new Exception('Image not exists');
118
        }
119
120
        if (is_null($height)) {
121
            $height = $width;
122
        }
123
        $imagick = new \Imagick(realpath($this->sImgPath));
124
125
        $canvasFactor = $width / $height;
126
127
        $origWidth  = $imagick->getImageWidth();
128
        $origHeight = $imagick->getImageHeight();
129
        $origFactor = $origWidth / $origHeight;
130
        if ($origFactor > $canvasFactor) {//za rozciągniety
131
            $imgWidth  = $width;
132
            $imgHeight = intval($width / $origFactor);
133
134
        } else {//za wysoki
135
            $imgHeight = $height;
136
            $imgWidth  = intval($height * $origFactor);
137
        }
138
139
140
        $imagick = $imagick->flattenImages();
141
        $imagick->setImageBackgroundColor(new \ImagickPixel('white'));
142
        $imagick->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);
143
        $imagick->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN);
144
145
        $colors = min(255, $imagick->getImageColors());
146
        $imagick->quantizeImage($colors, \Imagick::COLORSPACE_GRAY, 0, false, false);
147
        $imagick->setImageDepth(8 /* bits */);
148
        $imagick->resizeImage($imgWidth, $imgHeight, \Imagick::FILTER_LANCZOS, 1, false);
149
        $imagick->stripImage();
150
151
        $canvas = new \Imagick();
152
        $canvas->newImage($width, $height, new \ImagickPixel('white'));
153
        $canvas->compositeImage($imagick, \Imagick::COMPOSITE_DEFAULT, intval(($width - $imgWidth) / 2), intval(($height - $imgHeight) / 2));
154
        $canvas->setImageFormat('BMP');
155
156
        return $canvas;
157
    }
158
159
}
160