1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "effect_image_render.h"
17
18 #include "effect_utils.h"
19 #include "rs_trace.h"
20
21 namespace OHOS::Rosen {
22 static constexpr float GRAYSCALE_PARAONE = 0.2126f;
23 static constexpr float GRAYSCALE_PARATWO = 0.7152f;
24 static constexpr float GRAYSCALE_PARATHREE = 0.0722f;
25 static constexpr float RADIUS_THRESHOLD = 0.0f;
26 static constexpr float BRIGHTNESS_MIN_THRESHOLD = 0.0f;
27 static constexpr float BRIGHTNESS_MAX_THRESHOLD = 1.0f;
28
Blur(float radius,Drawing::TileMode tileMode)29 std::shared_ptr<EffectImageFilter> EffectImageFilter::Blur(float radius, Drawing::TileMode tileMode)
30 {
31 if (radius < RADIUS_THRESHOLD) {
32 return nullptr;
33 }
34
35 return std::make_shared<EffectImageBlurFilter>(radius, tileMode);
36 }
37
Brightness(float degree)38 std::shared_ptr<EffectImageFilter> EffectImageFilter::Brightness(float degree)
39 {
40 if (degree < BRIGHTNESS_MIN_THRESHOLD || degree > BRIGHTNESS_MAX_THRESHOLD) {
41 return nullptr;
42 }
43
44 float matrix[20] = {
45 1.0f, 0.0f, 0.0f, 0.0f, degree,
46 0.0f, 1.0f, 0.0f, 0.0f, degree,
47 0.0f, 0.0f, 1.0f, 0.0f, degree,
48 0.0f, 0.0f, 0.0f, 1.0f, 0.0f
49 };
50 auto colorFilter = Drawing::ColorFilter::CreateFloatColorFilter(matrix, Drawing::Clamp::NO_CLAMP);
51 auto filter = Drawing::ImageFilter::CreateColorFilterImageFilter(*colorFilter, nullptr);
52 return std::make_shared<EffectImageDrawingFilter>(filter);
53 }
54
Grayscale()55 std::shared_ptr<EffectImageFilter> EffectImageFilter::Grayscale()
56 {
57 float matrix[20] = {
58 GRAYSCALE_PARAONE, GRAYSCALE_PARATWO, GRAYSCALE_PARATHREE, 0.0f, 0.0f,
59 GRAYSCALE_PARAONE, GRAYSCALE_PARATWO, GRAYSCALE_PARATHREE, 0.0f, 0.0f,
60 GRAYSCALE_PARAONE, GRAYSCALE_PARATWO, GRAYSCALE_PARATHREE, 0.0f, 0.0f,
61 0.0f, 0.0f, 0.0f, 1.0f, 0.0f
62 };
63 auto colorFilter = Drawing::ColorFilter::CreateFloatColorFilter(matrix, Drawing::Clamp::NO_CLAMP);
64 auto filter = Drawing::ImageFilter::CreateColorFilterImageFilter(*colorFilter, nullptr);
65 return std::make_shared<EffectImageDrawingFilter>(filter);
66 }
67
Invert()68 std::shared_ptr<EffectImageFilter> EffectImageFilter::Invert()
69 {
70 /* invert matrix */
71 float matrix[20] = {
72 -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
73 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
74 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
75 0.0f, 0.0f, 0.0f, 1.0f, 0.0f
76 };
77 auto colorFilter = Drawing::ColorFilter::CreateFloatColorFilter(matrix, Drawing::Clamp::NO_CLAMP);
78 auto filter = Drawing::ImageFilter::CreateColorFilterImageFilter(*colorFilter, nullptr);
79 return std::make_shared<EffectImageDrawingFilter>(filter);
80 }
81
ApplyColorMatrix(const Drawing::ColorMatrix & colorMatrix)82 std::shared_ptr<EffectImageFilter> EffectImageFilter::ApplyColorMatrix(const Drawing::ColorMatrix& colorMatrix)
83 {
84 float matrix[20] = {};
85 colorMatrix.GetArray(matrix);
86 auto colorFilter = Drawing::ColorFilter::CreateFloatColorFilter(matrix, Drawing::Clamp::NO_CLAMP);
87 auto filter = Drawing::ImageFilter::CreateColorFilterImageFilter(*colorFilter, nullptr);
88 return std::make_shared<EffectImageDrawingFilter>(filter);
89 }
90
Apply(const std::shared_ptr<EffectImageChain> & image)91 DrawingError EffectImageDrawingFilter::Apply(const std::shared_ptr<EffectImageChain>& image)
92 {
93 if (image == nullptr) {
94 return DrawingError::ERR_IMAGE_NULL;
95 }
96
97 return image->ApplyDrawingFilter(filter_);
98 }
99
Apply(const std::shared_ptr<EffectImageChain> & image)100 DrawingError EffectImageBlurFilter::Apply(const std::shared_ptr<EffectImageChain>& image)
101 {
102 if (image == nullptr) {
103 return DrawingError::ERR_IMAGE_NULL;
104 }
105
106 return image->ApplyBlur(radius_, tileMode_);
107 }
108
Render(const std::shared_ptr<Media::PixelMap> & srcPixelMap,const std::vector<std::shared_ptr<EffectImageFilter>> & effectFilters,bool forceCPU,std::shared_ptr<Media::PixelMap> & dstPixelMap)109 DrawingError EffectImageRender::Render(const std::shared_ptr<Media::PixelMap>& srcPixelMap,
110 const std::vector<std::shared_ptr<EffectImageFilter>>& effectFilters, bool forceCPU,
111 std::shared_ptr<Media::PixelMap>& dstPixelMap)
112 {
113 ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "EffectImageRender::Render");
114
115 auto ret = DrawingError::ERR_OK;
116 do {
117 auto effectImage = std::make_shared<EffectImageChain>();
118 ret = effectImage->Prepare(srcPixelMap, forceCPU);
119 if (ret != DrawingError::ERR_OK) {
120 EFFECT_LOG_E("EffectImageRender::Render: Failed to prepare image, ret=%{public}d.", ret);
121 break;
122 }
123
124 for (const auto& filter : effectFilters) {
125 if (filter == nullptr) {
126 continue;
127 }
128
129 ret = filter->Apply(effectImage);
130 if (ret != DrawingError::ERR_OK) {
131 EFFECT_LOG_E("EffectImageRender::Render: Failed to apply filter, ret=%{public}d.", ret);
132 break;
133 }
134 }
135 if (ret != DrawingError::ERR_OK) {
136 break;
137 }
138
139 ret = effectImage->Draw();
140 if (ret != DrawingError::ERR_OK) {
141 EFFECT_LOG_E("EffectImageRender::Render: Failed to draw image, ret=%{public}d.", ret);
142 break;
143 }
144
145 dstPixelMap = effectImage->GetPixelMap();
146 } while (false);
147
148 ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
149 return ret;
150 }
151 } // namespace OHOS::Rosen