Beispiel #1
0
		/// <summary>
		/// Draw the specified x, y, source and considerAlpha.
		/// </summary>
		/// <param name="x">The x coordinate.</param>
		/// <param name="y">The y coordinate.</param>
		/// <param name="source">Source.</param>
		/// <param name="considerAlpha">If set to <c>true</c> consider alpha.</param>
		public void Draw(int x, int y, Image8i source, bool considerAlpha)
		{
			if (!considerAlpha || source.ChannelFormat == ChannelFormat.BGR ||
			    source.ChannelFormat == ChannelFormat.RGB || source.ChannelFormat == ChannelFormat.Gray)
			{
				Draw(x, y, source);
				return;
			}

			if (x >= Width || y >= Height) throw new ArgumentOutOfRangeException("x or y", "Out of image.");
			if (x + source.Width < 0 || y + source.Height < 0) throw new ArgumentOutOfRangeException("x or y", "Out of image.");

			Image8i sourceImage = null;

			switch (ChannelFormat)
			{
				case ChannelFormat.Gray:
					{
						sourceImage = source.ToChannelFormatGrayAlpha();
						break;
					}
				case ChannelFormat.GrayAlpha:
					{
						sourceImage = source.ToChannelFormatGrayAlpha();
						break;
					}
				case ChannelFormat.RGB:
					{
						sourceImage = source.ToChannelFormatRGBA();
						break;
					}
				case ChannelFormat.RGBA:
					{
						sourceImage = source.ToChannelFormatRGBA();
						break;
					}
				case ChannelFormat.BGR:
					{
						sourceImage = source.ToChannelFormatBGRA();
						break;
					}
				case ChannelFormat.BGRA:
					{
						sourceImage = source.ToChannelFormatBGRA();
						break;
					}
			}

			uint bpp = GetBytePerPixelFromChannelFormat(source.ChannelFormat);

			unsafe
			{
				fixed(byte* src_=sourceImage.imageData, dst_=imageData)
				{
					uint start = (uint)System.Math.Max(-x, 0);
					uint end = (uint)System.Math.Min(source.Width, Width - x);

					uint jstart = (uint)System.Math.Max(-y, 0);
					uint jend = (uint)System.Math.Min(source.Height, Height - y);

					if (ChannelFormat == ChannelFormat.BGR || ChannelFormat == ChannelFormat.RGB || ChannelFormat == ChannelFormat.Gray)
					{
						uint dbpp = GetBytePerPixelFromChannelFormat(ChannelFormat);

						byte* src__ = src_ + start * bpp;
						byte* dst__ = dst_ + x * dbpp + start * dbpp;

						uint sw = source.Width * bpp;
						uint dw = Width * dbpp;

						if (ChannelFormat == ChannelFormat.BGR || ChannelFormat == ChannelFormat.RGB)
						{
							for (uint j = jstart; j < jend; j++)
							{
								byte* src = src__ + sw * j;
								byte* dst = dst__ + dw * (y + j);

								for (uint i = start; i < end; i++)
								{
									byte sr = *src++;
									byte sg = *src++;
									byte sb = *src++;
									byte sa = *src++;

									if (sa != 0)
									{
										byte dr = *dst++;
										byte dg = *dst++;
										byte db = *dst++;
										dst -= 3;

										double a2 = sa / 255.0;
										double a1 = 1 - a2;
										*dst++ = (byte)(dr * a1 + sr * a2);
										*dst++ = (byte)(dg * a1 + sg * a2);
										*dst++ = (byte)(db * a1 + sb * a2);
									}
									else dst += 3;
								}
							}
						}
						else // GRAY
						{
							for (uint j = jstart; j < jend; j++)
							{
								byte* src = src__ + sw * j;
								byte* dst = dst__ + dw * (y + j);

								for (uint i = start; i < end; i++)
								{
									byte sg = *src++;
									byte sa = *src++;

									if (sa != 0)
									{
										byte dg = *dst;

										double a2 = sa / 255.0;
										double a1 = 1 - a2;
										*dst++ = (byte)(dg * a1 + sg * a2);
									}
									else dst++;
								}
							}
						} // end if RGB || BGR
					}
					else // 2x alpha image
					{
						byte* src__ = src_ + start * bpp;
						byte* dst__ = dst_ + x * bpp + start * bpp;

						uint sw = source.Width * bpp;
						uint dw = Width * bpp;

						if (ChannelFormat == ChannelFormat.BGRA || ChannelFormat == ChannelFormat.RGBA)
						{
							for (uint j = jstart; j < jend; j++)
							{
								byte* src = src__ + sw * j;
								byte* dst = dst__ + dw * (y + j);

								for (uint i = start; i < end; i++)
								{
									byte sr = *src++;
									byte sg = *src++;
									byte sb = *src++;
									byte sa = *src++;

									if (sa != 0)
									{
										byte dr = *dst++;
										byte dg = *dst++;
										byte db = *dst++;
										byte da = *dst++;
										dst -= 4;

										double a2 = sa / 255.0;
										double a1 = 1 - a2;
										*dst++ = (byte)(dr * a1 + sr * a2);
										*dst++ = (byte)(dg * a1 + sg * a2);
										*dst++ = (byte)(db * a1 + sb * a2);
										*dst++ = da;
									}
									else dst += 4;
								}
							}
						}
						else // GRAYALPHA
						{
							for (uint j = jstart; j < jend; j++)
							{
								byte* src = src__ + sw * j;
								byte* dst = dst__ + dw * (y + j);

								for (uint i = start; i < end; i++)
								{
									byte sg = *src++;
									byte sa = *src++;

									if (sa != 0)
									{
										byte dg = *dst++;
										byte da = *dst++;
										dst -= 2;

										double a2 = sa / 255.0;
										double a1 = 1 - a2;
										*dst++ = (byte)(dg * a1 + sg * a2);
										*dst++ = da;
									}
									else dst += 2;
								}
							}
						} // end if RGBA || BGRA
					} // end if 2x Alpha-Bild
				} // fixed
			} // unsafe
		}