YSTest: ImageProcessing.cpp 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

ImageProcessing.cpp
浏览该文件的文档.
1 /*
2 © 2014-2015 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #include "YSLib/UI/YModules.h"
29 #include YFM_YSLib_Service_ImageProcessing
30 #include YFM_YSLib_UI_YComponent // for to_string;
31
32 namespace YSLib
33 {
34
35 namespace Drawing
36 {
37
38 CompactPixmap
39 Zoom(const HBitmap& bitmap, ImageScale ratio)
40 {
41 YAssert(bool(bitmap), "Invalid bitmap found.");
42
43 const Size bmp_size(bitmap.GetSize());
44
45 YAssert(!bmp_size.IsUnstrictlyEmpty(), "Invalid size found.");
46 YTraceDe(Informative, "Unscaled image size = %s, requested ratio = %f.",
47 to_string(bmp_size).c_str(), double(ratio));
48 if(abs(ratio - 1) < std::numeric_limits<ImageScale>::epsilon())
49 return bitmap;
50
51 const Size zoomed_size(round(bmp_size.Width * float(ratio)),
52 round(bmp_size.Height * float(ratio)));
53
54 YTraceDe(Informative, "Zoomed image ratio = %f, with size = %s.",
55 double(ratio), to_string(zoomed_size).c_str());
56 return HBitmap(bitmap, zoomed_size,
57 ratio < 2 ? SamplingFilter::Bilinear : SamplingFilter::Bicubic);
58 }
59
60
61 shared_ptr<Image>
62 ZoomedImageCache::Lookup(ImageScale scale, size_t idx)
63 {
64 YAssert(idx < bitmaps.size(), "Invalid index found.");
65
66 return ystdex::cache_lookup(cache, CacheKey(scale, idx), [&]{
67 return make_shared<Image>(Zoom(bitmaps[idx], scale));
68 });
69 }
70
71
72 ImagePages::ImagePages(ZoomedImageCache&& c, const Size& min_size,
73 const Size& max_size, ImageScale init_scale)
74 : cache(std::move(c)),
75 base_size([&](const ZoomedImageCache::Container& bmps) -> Size {
76 YAssert(!max_size.IsUnstrictlyEmpty(), "Empty maximum size found.");
77
78 if(bmps.empty())
79 return max_size;
80
81 const auto& first_size(bmps[0].GetSize());
82
83 TryRet(GetLogicalSizeOf(bmps[0]) | first_size)
84 CatchIgnore(GeneralEvent&)
85 return first_size;
86 }(cache.GetBitmaps())), scale([&, init_scale]() -> ImageScale {
87 return init_scale < MinScale ? ImageScale(cache.GetBitmaps().empty()
88 ? 1.F : ScaleMin(max_size, base_size)) : init_scale;
89 }())
90 {
91 YAssert((min_size & max_size) == min_size, "Invalid size arguments found.");
92 YTraceDe(Informative, "Base size = %s.", to_string(base_size).c_str());
93 YTraceDe(Informative, "Automatically rescaled, scale = %f.", double(scale));
94 LoadContent();
95 // YTraceDe(Informative, "Format = %d.", bitmap.GetFormat());
96 yunseq(view_size = min_size | Brush.ImagePtr->GetSize(),
97 Brush.Update = Drawing::UpdateRotatedBrush<>);
98 AdjustOffset(view_size);
99 }
100
101 void
102 ImagePages::AdjustOffset(const Size& cont_size)
103 {
104 YAssertNonnull(Brush.ImagePtr);
105
106 auto& dst(Brush.DstOffset);
107 const auto& size(Brush.ImagePtr->GetSize());
108
109 // XXX: Conversion to 'SPos' might be implementation-defined.
110 if(cont_size.Width >= size.Width)
111 dst.X = HalfDifference(SPos(cont_size.Width), SPos(size.Width));
112 if(cont_size.Height >= size.Height)
113 dst.Y = HalfDifference(SPos(cont_size.Height), SPos(size.Height));
114 YTraceDe(Informative, "Adjusted destination offset = %s.",
115 to_string(dst).c_str());
116 }
117
118 void
119 ImagePages::Resize(const Size& new_size)
120 {
121 YTraceDe(Informative, "Requested resized size = %s.",
122 to_string(new_size).c_str());
123 YAssertNonnull(Brush.ImagePtr);
124
125 const Point offset(view_size.Width / 2, view_size.Height / 2);
126 const Point new_offset(new_size.Width / 2, new_size.Height / 2);
127
128 YTraceDe(Informative, "Zoomed ratio = %f, fixed offset = %s, "
129 "fixed new offset = %s.", double(scale), to_string(offset).c_str(),
130 to_string(new_offset).c_str());
131 Brush.DstOffset += new_offset - offset;
132 AdjustOffset(view_size = new_size);
133 }
134
135 void
136 ImagePages::LoadContent()
137 {
138 YAssert(std::numeric_limits<ImageScale>::epsilon() < abs(scale),
139 "Invalid ratio value found.");
140 Brush.ImagePtr = cache.Lookup(scale, index);
141 }
142
143 bool
144 ImagePages::SwitchPage(size_t page)
145 {
146 YAssert(ZoomedImageCache::Container::size_type(page) < GetCount(),
147 "Invalid index found.");
148 if(page != index)
149 {
150 index = ZoomedImageCache::Container::size_type(page);
151 YTraceDe(Informative, "Page switched: %zu/%zu.", index + 1,
152 cache.GetBitmaps().size());
153 LoadContent();
154 return true;
155 }
156 return {};
157 }
158
159 bool
160 ImagePages::Zoom(float delta, const Point& offset)
161 {
162 YTraceDe(Informative, "Action: zoom, with delta = %f%%.",
163 double(delta * 100.F));
164 return ZoomTo(scale + delta, offset);
165 }
166
167 bool
168 ImagePages::ZoomByRatio(float ratio, const Point& offset, float err)
169 {
170 YTraceDe(Informative, "Action: zoom, with ratio = %f%%.",
171 double(ratio * 100.F));
172 if(ratio > 0)
173 return Zoom(ystdex::round_in((ratio - 1.F) * scale, err), offset);
174 else
175 YTraceDe(Warning, "Invalid ratio found.");
176 return {};
177 }
178
179 bool
180 ImagePages::ZoomTo(float dst_scale, const Point& offset)
181 {
182 if(!std::isfinite(dst_scale))
183 throw std::invalid_argument("Invalid destination scale value found.");
184
185 ImageScale new_scale(dst_scale);
186
187 RestrictInClosedInterval(new_scale, MinScale, MaxScale);
188 YTraceDe(Informative, "Requested zoomed ratio = %f, fixed offset = %s.",
189 double(new_scale), to_string(offset).c_str());
190 if(std::numeric_limits<ImageScale>::epsilon() < abs(new_scale - scale))
191 {
192 const auto old(scale);
193
194 scale = new_scale;
195 LoadContent();
196 Brush.DstOffset = offset - (offset - Brush.DstOffset) * (scale / old);
197 AdjustOffset(view_size);
198 return true;
199 }
200 return {};
201 }
202
203 } // namespace Drawing;
204
205 } // namespace YSLib;
206
YSLib::HalfDifference
yconstfn YB_STATELESS _type HalfDifference(_type x, _type y)
计算指定类型的差值的一半。
Definition: YCoreUtilities.h:72
YSLib::Drawing::ImagePages::MaxScale
ImageScale MaxScale
Definition: ImageProcessing.h:116
platform::Descriptions::Warning
Definition: YCommon.h:157
platform::Descriptions::Informative
Definition: YCommon.h:159
YSLib::Drawing::ImageBrush::DstOffset
Point DstOffset
Definition: YBrush.h:142
YSLib::GeneralEvent
std::runtime_error GeneralEvent
一般运行时异常事件类。
Definition: YException.h:45
ystdex::fixed_point< yimpl(std::uint32_t, 12U)>
YSLib::Drawing::GetLogicalSizeOf
Size GetLogicalSizeOf(const HBitmap &bmp)
Definition: Image.cpp:445
YSLib::Drawing::ImagePages::index
size_t index
Definition: ImageProcessing.h:120
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:45
YSLib::RestrictInClosedInterval
void RestrictInClosedInterval(_type &v, const _type &a, const _type &b) ynothrow
约束 v 在闭区间 [a, b] 中。
Definition: YCoreUtilities.h:207
YSLib::Drawing::Size::Width
SDst Width
Definition: YGDIBase.h:302
YSLib::Drawing::ScaleMin
yconstfn _tScalar ScaleMin(const Size &x, const Size &y, _tScalar threshold=1.F)
计算两个大小和阈值限定的最小缩放值。
Definition: YGDIBase.h:526
YSLib::Drawing::ZoomedImageCache::bitmaps
Container bitmaps
Definition: ImageProcessing.h:79
YTraceDe
#define YTraceDe(...)
YCLib 默认调试跟踪。
Definition: Debug.h:305
CatchIgnore
#define CatchIgnore(_ex)
指定异常处理器忽略指定异常。
Definition: YBaseMacro.h:133
ystdex::round_in
_type round_in(_type x, _type err)
Definition: rational.hpp:80
NPL::dst
YF_API const char src const string const char * dst
Definition: Dependency.h:93
std
Definition: memory.hpp:1100
YSLib::Drawing::to_string
string to_string(const ImageTag &tag, ImageMetadataModel model)
Definition: Image.cpp:699
YAssertNonnull
#define YAssertNonnull(_expr)
Definition: cassert.h:114
platform::SPos
std::int16_t SPos
屏幕坐标度量。
Definition: Video.h:42
YSLib::Drawing::ImagePages::Resize
void Resize(const Size &)
Definition: ImageProcessing.cpp:119
YSLib::Drawing::ZoomedImageCache::cache
BitmapCache cache
Definition: ImageProcessing.h:80
YSLib::Drawing::c
The boundary is out of the const Graphics const Rect const Point const Point Color c const Rect const Rect Color c
Definition: YDraw.h:174
ystdex::size
auto size(const _tRange &c) -> decltype(c.size())
类容器访问。
Definition: range.hpp:233
YSLib::YAssert
YAssert(!(v< Deref(a)),"Value less than lower bound found.")
YSLib::Drawing::HBitmap
位图句柄：指向位图数据。
Definition: Image.h:298
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:996
YSLib::Drawing::ImagePages::ZoomByRatio
const Point &bool ZoomByRatio(float, const Point &, float=0.F)
按指定的相对比例、偏移量和允许的误差缩放。 异常中立：由 ZoomTo 抛出。
Definition: ImageProcessing.cpp:168
YSLib::Drawing::ImageBrush::ImagePtr
shared_ptr< Drawing::Image > ImagePtr
Definition: YBrush.h:140
YSLib::Drawing::Size
屏幕区域大小。
Definition: YGDIBase.h:293
YSLib::Drawing::ImagePages::SwitchPage
bool SwitchPage(size_t)
Definition: ImageProcessing.cpp:144
TryRet
#define TryRet(...)
指定表达式在 try 块中求值并返回。
Definition: YBaseMacro.h:124
Drawing
YSLib::Drawing::ImagePages::ZoomTo
bool ZoomTo(float, const Point &)
按指定的绝对比例和偏移量缩放。
Definition: ImageProcessing.cpp:180
YModules.h
YSLib::Drawing::Size::Height
SDst Height
宽和高。
Definition: YGDIBase.h:302
YSLib::Drawing::Zoom
YF_API CompactPixmap Zoom(const HBitmap &, ImageScale)
缩放位图。
Definition: ImageProcessing.cpp:39
YSLib::Drawing::ImagePages::Brush
ImageBrush Brush
Definition: ImageProcessing.h:137
NPL::c_str
YF_API const char src c_str())) YF_API void InstallDirectory(const string &
安装目录：复制目录树。
ystdex::cache_lookup
auto cache_lookup(_tMap &cache, const _tKey &key, _func init, _tParams &&...args) -> decltype((cache.begin() ->second))
以指定的关键字查找作为缓存的无序关联容器， 若没有找到使用指定的可调用对象和参数初始化内容。 ...
Definition: cache.hpp:369
YSLib::Drawing::ImagePages::MinScale
ImageScale MinScale
Definition: ImageProcessing.h:115
YSLib::Drawing::ImagePages::LoadContent
void LoadContent()
Definition: ImageProcessing.cpp:136
YSLib::Drawing::ZoomedImageCache::CacheKey
pair< ImageScale, size_t > CacheKey
Definition: ImageProcessing.h:68
YSLib::Drawing::ImagePages::scale
ImageScale scale
缩放比例。
Definition: ImageProcessing.h:131
YSLib::Drawing::ZoomedImageCache
缩放图像缓冲。
Definition: ImageProcessing.h:64
YSLib::Drawing::ZoomedImageCache::Lookup
const Container bitmaps shared_ptr< Image > Lookup(ImageScale, size_t)
Definition: ImageProcessing.cpp:62
YSLib::Drawing::ImagePages::view_size
Size view_size
Definition: ImageProcessing.h:133
YSLib::Drawing::ImagePages::ImagePages
ImagePages(const _type &path, const Size &min_size, const Size &max_size, ImageScale init_scale={})
构造：使用指定路径、显示区域下限、显示区域上限和起始缩放比例。
Definition: ImageProcessing.h:148
YSLib::Drawing::ImagePages::cache
ZoomedImageCache cache
Definition: ImageProcessing.h:121
YSLib::Drawing::ImagePages::AdjustOffset
const vector< HBitmap > cache index const Size view_size void AdjustOffset(const Size &)
Definition: ImageProcessing.cpp:102
YSLib::Drawing::ImageScale
ystdex::fixed_point< yimpl(std::uint32_t, 12U)> ImageScale
图像缩放类型。
Definition: ImageProcessing.h:49
YSLib::Drawing::GBinaryGroup< SPos >