Exemplo n.º 1
0
		void GdiPlusAccess::AverageBlur(Gdiplus::BitmapData &data, size_t xRadius, size_t yRadius) {
			struct ColumnCache {
				List<DArr<4>> Content;
				size_t Index = 0;
			};
			Queue<ColumnCache> cache;
			List<List<DArr<4>>> result;
			for (size_t x = 0; x < data.Width; ++x) {
				for (size_t cx = (cache.Count() == 0 ? 0 : x + xRadius); cx < data.Width && cx <= x + xRadius; ++cx) {
					ColumnCache curCol;
					curCol.Index = cx;
					curCol.Content.PushBack(ColorToDArr(GetColor(data, cx, 0)) * static_cast<double>(yRadius + 1));
					for (size_t ay = 1; ay <= yRadius; ++ay) {
						curCol.Content.Last() += ColorToDArr(GetColor(data, cx, (ay >= data.Height ? data.Height - 1 : ay)));
					}
					for (size_t cy = 1; cy < data.Height; ++cy) {
						DArr<4> lpx = curCol.Content.Last();
						curCol.Content.PushBack(lpx);
						DArr<4> &curPx = curCol.Content.Last();
						curPx -= ColorToDArr(GetColor(data, cx, (cy < yRadius + 1 ? 0 : cy - yRadius - 1)));
						curPx += ColorToDArr(GetColor(data, cx, Core::Math::Min(cy + yRadius, static_cast<size_t>(data.Height) - 1)));
					}
					cache.PushHead(curCol);
				}
				while (cache.PeekTail().Index + xRadius < x) {
					cache.PopTail();
				}
				result.PushBack(List<DArr<4>>());
				List<DArr<4>> &curList = result.Last();
				for (size_t y = 0; y < data.Height; ++y) {
					curList.PushBack(DArr<4>());
					DArr<4> &curPx = curList.Last();
					cache.ForEachTailToHead([&](const ColumnCache &cc) {
						size_t repeat = 1;
						if (cc.Index == 0) {
							repeat = xRadius + 1 - x;
						} else if (cc.Index == data.Width - 1) {
							repeat = x + xRadius + 2 - data.Width;
						}
						for (size_t i = 0; i < repeat; ++i) {
							curPx += cc.Content[static_cast<size_t>(y)];
						}
						return true;
					});
				}
			}
			for (size_t x = 0; x < data.Width; ++x) {
				for (size_t y = 0; y < data.Height; ++y) {
					GetColor(data, x, y) = DArrToColor(result[x][y] / ((2 * xRadius + 1) * (2 * yRadius + 1)));
				}
			}
		}