Completed
Push — master ( 261d31...f53ed5 )
by Marcin
02:14
created

ElemBitmap::resizeImage()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 44
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 44
ccs 0
cts 29
cp 0
rs 8.439
c 0
b 0
f 0
cc 5
eloc 30
nc 5
nop 2
crap 30
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 $sImgUrl
0 ignored issues
show
Bug introduced by
There is no parameter named $sImgUrl. 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...
63
     */
64
    public function __construct(string $sImgPath, Rectangle $oRectangle)
65
    {
66
        parent::__construct();
67
        $this->sImgPath = $sImgPath;
68
        $this->oCanvas  = $oRectangle;
69
        $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...
70
        $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...
71
72
    }
73
74
    /**
75
     * @return \mrcnpdlk\Grandstream\XMLApp\MyXML
76
     */
77
    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...
78
    {
79
        $oXml = new MyXML('DisplayBitmap');
80
81
        $oXml->asObject()->addAttribute('isfile', $this->isFile);
82
        $oXml->asObject()->addAttribute('isflash', $this->isFlash);
83
        $oXml->asObject()->addChild('X', $this->getPoint()->getX());
84
        $oXml->asObject()->addChild('Y', $this->getPoint()->getY());
85
        $oXml->asObject()->addChild('Bitmap', $this->getBase64());
86
87
        return $oXml;
88
    }
89
90
    /**
91
     * @return string
92
     */
93
    private function getBase64()
94
    {
95
        try {
96
            if (!extension_loaded('imagick')) {
97
                throw new \Exception('No imagick loaded');
98
            }
99
100
            return base64_encode($this->resizeImage($this->oCanvas->getWidth(), $this->oCanvas->getHeight())->getImageBlob());
101
        } catch (\Exception $e) {
102
            return '';
103
        }
104
    }
105
106
    /**
107
     * @param int      $width
108
     * @param int|null $height
109
     *
110
     * @return \Imagick
111
     * @throws \mrcnpdlk\Grandstream\XMLApp\Exception
112
     */
113
    private function resizeImage(int $width = 100, int $height = null)
114
    {
115
        if (!file_exists($this->sImgPath) || !is_readable($this->sImgPath)) {
116
            throw new Exception('Image not exists');
117
        }
118
119
        if (is_null($height)) {
120
            $height = $width;
121
        }
122
        $imagick = new \Imagick(realpath($this->sImgPath));
123
124
        $canvasFactor = $width / $height;
125
126
        $origWidth  = $imagick->getImageWidth();
127
        $origHeight = $imagick->getImageHeight();
128
        $origFactor = $origWidth / $origHeight;
129
        if ($origFactor > $canvasFactor) {//za rozciągniety
130
            $imgWidth  = $width;
131
            $imgHeight = intval($width / $origFactor);
132
133
        } else {//za wysoki
134
            $imgHeight = $height;
135
            $imgWidth  = intval($height * $origFactor);
136
        }
137
138
139
        $imagick = $imagick->flattenImages();
140
        $imagick->setImageBackgroundColor(new \ImagickPixel('white'));
141
        $imagick->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);
142
        $imagick->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN);
143
144
        $colors = min(255, $imagick->getImageColors());
145
        $imagick->quantizeImage($colors, \Imagick::COLORSPACE_GRAY, 0, false, false);
146
        $imagick->setImageDepth(8 /* bits */);
147
        $imagick->resizeImage($imgWidth, $imgHeight, \Imagick::FILTER_LANCZOS, 1, false);
148
        $imagick->stripImage();
149
150
        $canvas = new \Imagick();
151
        $canvas->newImage($width, $height, new \ImagickPixel('white'));
152
        $canvas->compositeImage($imagick, \Imagick::COMPOSITE_DEFAULT, intval(($width - $imgWidth) / 2), intval(($height - $imgHeight) / 2));
153
        $canvas->setImageFormat('BMP');
154
155
        return $canvas;
156
    }
157
158
}
159