예제 #1
0
		Image8i ToReducedByImageHorizontal(uint m)
		{
			if ((Width * Height) == 0) return new Image8i(0, 0, ChannelFormat);
			uint w = Width / m;
			uint wh = w * Height;

			if (ChannelFormat == ChannelFormat.Gray)
			{
				Image8i ret = new Image8i(w, Height, ChannelFormat);
				if (ret.imageData == null) return ret;

				byte[] dst = ret.imageData;
				uint ind = 0;
				byte[] src = imageData;
				uint inds = 0;

				for (uint y = 0; y < wh; y++)
				{
					uint sum = 0;
					for (uint z = 0; z < m; z++) sum += src[inds++];
					dst[ind++] = (byte)(sum / m);
				}

				return ret;
			}

			if (ChannelFormat == ChannelFormat.RGB || ChannelFormat == ChannelFormat.BGR)
			{
				Image8i ret = new Image8i(w, Height, ChannelFormat);
				if (ret.imageData == null) return ret;

				byte[] dst = ret.imageData;
				uint ind = 0;
				byte[] src = imageData;
				uint inds = 0;

				for (uint y = 0; y < wh; y++)
				{
					uint sumr = 0, sumg = 0, sumb = 0;

					for (uint z = 0; z < m; z++)
					{
						sumr += src[inds++];
						sumg += src[inds++];
						sumb += src[inds++];
					}

					dst[ind++] = (byte)(sumr / m);
					dst[ind++] = (byte)(sumg / m);
					dst[ind++] = (byte)(sumb / m);
				}

				return ret;
			}

			if (ChannelFormat == ChannelFormat.RGBA || ChannelFormat == ChannelFormat.BGRA)
			{
				Image8i ret = new Image8i(w, Height, ChannelFormat);
				if (ret.imageData == null) return ret;

				byte[] dst = ret.imageData;
				uint ind = 0;
				byte[] src = imageData;
				uint inds = 0;

				for (uint y = 0; y < wh; y++)
				{
					uint sumr = 0, sumg = 0, sumb = 0, suma = 0;

					for (uint z = 0; z < m; z++)
					{
						byte r = src[inds++];
						byte g = src[inds++];
						byte b = src[inds++];
						uint a = src[inds++];
						sumr += r * a;
						sumg += g * a;
						sumb += b * a;
						suma += a;
					}

					if (suma == 0)
					{
						dst[ind++] = 0;
						dst[ind++] = 0;
						dst[ind++] = 0;
						dst[ind++] = 0;
					}
					else
					{
						dst[ind++] = (byte)(sumr / suma);
						dst[ind++] = (byte)(sumg / suma);
						dst[ind++] = (byte)(sumb / suma);
						dst[ind++] = (byte)(suma / m);
					}
				}

				return ret;
			}

			if (ChannelFormat == ChannelFormat.GrayAlpha)
			{
				Image8i ret = new Image8i(w, Height, ChannelFormat);
				if (ret.imageData == null) return ret;

				byte[] dst = ret.imageData;
				uint ind = 0;
				byte[] src = imageData;
				uint inds = 0;

				for (uint y = 0; y < wh; y++)
				{
					uint sumg = 0, suma = 0;

					for (uint z = 0; z < m; z++)
					{
						byte g = src[inds++];
						uint a = src[inds++];
						sumg += g * a;
						suma += a;
					}

					if (suma == 0)
					{
						dst[ind++] = 0;
						dst[ind++] = 0;
					}
					else
					{
						dst[ind++] = (byte)(sumg / suma);
						dst[ind++] = (byte)(suma / m);
					}
				}

				return ret;
			}

			return new Image8i(0, 0, ChannelFormat);
		}
예제 #2
0
		Image8i ToReducedByImageVertical(uint n)
		{
			if ((Width * Height) == 0) return new Image8i(0, 0, ChannelFormat);
			uint h = Height / n;

			if (ChannelFormat == ChannelFormat.Gray)
			{
				Image8i ret = new Image8i(Width, h, ChannelFormat);
				if (ret.imageData == null) return ret;

				for (uint x = 0; x < Width; x++)
				{
					byte[] dst = ret.imageData;
					uint ind = x;
					byte[] src = imageData;
					uint inds = x;

					for (uint y = 0; y < h; y++)
					{
						uint sum = 0;
						for (uint z = 0; z < n; z++)
						{
							sum += src[inds];
							inds += Width;
						}

						dst[ind] = (byte)(sum / n);
						ind += Width;
					}
				}

				return ret;
			}

			if (ChannelFormat == ChannelFormat.RGB || ChannelFormat == ChannelFormat.BGR)
			{
				Image8i ret = new Image8i(Width, h, ChannelFormat);
				if (ret.imageData == null) return ret;

				uint wb = 3 * Width - 2;

				for (uint x = 0; x < Width; x++)
				{
					byte[] dst = ret.imageData;
					uint ind = x * 3;
					byte[] src = imageData;
					uint inds = x * 3;

					for (uint y = 0; y < h; y++)
					{
						uint sumr = 0, sumg = 0, sumb = 0;

						for (uint z = 0; z < n; z++)
						{
							sumr += src[inds++];
							sumg += src[inds++];
							sumb += src[inds];
							inds += wb;
						}

						dst[ind++] = (byte)(sumr / n);
						dst[ind++] = (byte)(sumg / n);
						dst[ind] = (byte)(sumb / n);
						ind += wb;
					}
				}

				return ret;
			}

			if (ChannelFormat == ChannelFormat.RGBA || ChannelFormat == ChannelFormat.BGRA)
			{
				Image8i ret = new Image8i(Width, h, ChannelFormat);
				if (ret.imageData == null) return ret;

				uint wb = 4 * Width - 3;

				for (uint x = 0; x < Width; x++)
				{
					byte[] dst = ret.imageData;
					uint ind = x * 4;
					byte[] src = imageData;
					uint inds = x * 4;

					for (uint y = 0; y < h; y++)
					{
						uint sumr = 0, sumg = 0, sumb = 0, suma = 0;

						for (uint z = 0; z < n; z++)
						{
							byte r = src[inds++];
							byte g = src[inds++];
							byte b = src[inds++];
							uint a = src[inds];
							inds += wb;
							sumr += r * a;
							sumg += g * a;
							sumb += b * a;
							suma += a;
						}

						if (suma == 0)
						{
							dst[ind++] = 0;
							dst[ind++] = 0;
							dst[ind++] = 0;
							dst[ind] = 0;
						}
						else
						{
							dst[ind++] = (byte)(sumr / suma);
							dst[ind++] = (byte)(sumg / suma);
							dst[ind++] = (byte)(sumb / suma);
							dst[ind] = (byte)(suma / n);
						}

						ind += wb;
					}
				}

				return ret;
			}

			if (ChannelFormat == ChannelFormat.GrayAlpha)
			{
				Image8i ret = new Image8i(Width, h, ChannelFormat);
				if (ret.imageData == null) return ret;

				uint wb = 2 * Width - 1;

				for (uint x = 0; x < Width; x++)
				{
					byte[] dst = ret.imageData;
					uint ind = x * 2;
					byte[] src = imageData;
					uint inds = x * 2;

					for (uint y = 0; y < h; y++)
					{
						uint sumg = 0, suma = 0;

						for (uint z = 0; z < n; z++)
						{
							byte g = src[inds++];
							uint a = src[inds];
							inds += wb;
							sumg += g * a;
							suma += a;
						}

						if (suma == 0)
						{
							dst[ind++] = 0;
							dst[ind] = 0;
						}
						else
						{
							dst[ind++] = (byte)(sumg / suma);
							dst[ind] = (byte)(suma / n);
						}

						ind += wb;
					}
				}

				return ret;
			}

			return new Image8i(0, 0, ChannelFormat);
		}
예제 #3
0
		/// <summary>
		/// Converts to gray.
		/// </summary>
		/// <returns>The to gray.</returns>
		public Image8i ToChannelFormatGray()
		{
			if (ChannelFormat == ChannelFormat.Gray) return this;
			Image8i ret = new Image8i(Width, Height, ChannelFormat.Gray);
			if (ret.imageData == null) return ret;

			uint count = Width * Height;
			byte[] src = imageData;
			uint ind = 0;
			byte[] dst = ret.imageData;
			uint inds = 0;

			switch (ChannelFormat)
			{
				case ChannelFormat.GrayAlpha:
					{
						for (uint i = 0; i < count; i++)
						{
							dst[ind++] = src[inds++];
							inds++;
						}
						break;
					}
				case ChannelFormat.BGR:
					{
						for (uint i = 0; i < count; i++)
						{
							byte r = src[inds++];
							byte g = src[inds++];
							byte b = src[inds++];
							dst[ind++] = (byte)(0.299 * r + 0.587 * g + 0.114 * b);
						}
						break;
					}
				case ChannelFormat.RGB:
					{
						for (uint i = 0; i < count; i++)
						{
							byte b = src[inds++];
							byte g = src[inds++];
							byte r = src[inds++];
							dst[ind++] = (byte)(0.299 * r + 0.587 * g + 0.114 * b);
						}
						break;
					}
				case ChannelFormat.BGRA:
					{
						for (uint i = 0; i < count; i++)
						{
							byte r = src[inds++];
							byte g = src[inds++];
							byte b = src[inds++];
							inds++;
							dst[ind++] = (byte)(0.299 * r + 0.587 * g + 0.114 * b);
						}
						break;
					}
				case ChannelFormat.RGBA:
					{
						for (uint i = 0; i < count; i++)
						{
							byte b = src[inds++];
							byte g = src[inds++];
							byte r = src[inds++];
							inds++;
							dst[ind++] = (byte)(0.299 * r + 0.587 * g + 0.114 * b);
						}
						break;
					}
			}

			return ret;
		}
예제 #4
0
		/// <summary>
		/// Converts ToBGR
		/// </summary>
		/// <returns>The to BGR.</returns>
		public Image8i ToChannelFormatBGRA()
		{
			if (ChannelFormat == ChannelFormat.BGRA) return this;
			Image8i ret = new Image8i(Width, Height, ChannelFormat.BGRA);
			if (ret.imageData == null) return ret;

			uint count = Width * Height;
			byte[] src = imageData;
			uint ind = 0;
			byte[] dst = ret.imageData;
			uint inds = 0;
			switch (ChannelFormat)
			{
				case ChannelFormat.Gray:
					{
						for (uint i = 0; i < count; i++)
						{
							byte g = src[inds++];
							dst[ind++] = g;
							dst[ind++] = g;
							dst[ind++] = g;
							dst[ind++] = 255;
						}
						break;
					}
				case ChannelFormat.GrayAlpha:
					{
						for (uint i = 0; i < count; i++)
						{
							byte g = src[inds++];
							dst[ind++] = g;
							dst[ind++] = g;
							dst[ind++] = g;
							dst[ind++] = src[inds++];
						}
						break;
					}
				case ChannelFormat.RGB:
					{
						for (uint i = 0; i < count; i++)
						{
							byte r = src[inds++];
							byte g = src[inds++];
							dst[ind++] = src[inds++];
							dst[ind++] = g;
							dst[ind++] = r;
							dst[ind++] = 255;
						}
						break;
					}
				case ChannelFormat.RGBA:
					{
						for (uint i = 0; i < count; i++)
						{
							byte r = src[inds++];
							byte g = src[inds++];
							dst[ind++] = src[inds++];
							dst[ind++] = g;
							dst[ind++] = r;
							dst[ind++] = src[inds++];
						}
						break;
					}
				case ChannelFormat.BGR:
					{
						for (uint i = 0; i < count; i++)
						{
							dst[ind++] = src[inds++];
							dst[ind++] = src[inds++];
							dst[ind++] = src[inds++];
							dst[ind++] = 255;
						}
						break;
					}
			}

			return ret;
		}
예제 #5
0
		private Image8i Render(int width, int height, string onlyLayer)
		{
			Image8i ret = new Image8i((uint)width, (uint)height, ChannelFormat.RGBA);
			ret = ret.ToAlphaInvertedImage();

			foreach (LayerData i in Layers)
			{
				if (onlyLayer == "")
				{
					if (i.name == "Collision") continue;
				}
				else
				{
					if (i.name != onlyLayer) continue;
				}

				for (int y = 0; y < i.height; y++)
				{
					for (int x = 0; x < i.width; x++)
					{
						int number = i.data[x, y];
						if (number <= 0) continue; 
						Image8i Tile = GetTile(number);

						int CorFactorX = 0;
						int CorFactorY = (int)(Tile.Height - TileHeight);

						ret.Draw(x * TileWidth - CorFactorX, y * TileHeight - CorFactorY, Tile, true);
					}
				}
			
			}

			return ret;
		}
예제 #6
0
		public Image8i ToFlippedImageCounterDiagonal()
		{
			Image8i ret = new Image8i(Height, Width, ChannelFormat);
			if (ret.imageData == null) return ret;

			uint bpp = GetBytePerPixelFromChannelFormat(ChannelFormat);
			uint bw = Height * bpp;

			uint src = 0;
			uint dst = Width * bw - bpp;

			for (uint y = 0; y < Height; y++)
			{
				uint tmp = dst;
				for (uint x = 0; x < Width; x++)
				{
					for (uint i = 0; i < bpp; i++) ret.imageData[dst++] = imageData[src++];
					dst -= bw + bpp;
				}
				dst = tmp - bpp;
			}

			return ret;
		}
예제 #7
0
		public Image8i To180DegreeRotatedImage()
		{
			Image8i ret = new Image8i(Width, Height, ChannelFormat);
			if (ret.imageData == null) return ret;

			uint bpp = GetBytePerPixelFromChannelFormat(ChannelFormat);
			uint bw = Width * bpp;

			uint src = 0;
			uint dst = Height * bw;
			dst -= bpp;

			for (uint y = 0; y < Height; y++)
			{
				for (uint x = 0; x < Width; x++)
				{
					for (uint i = 0; i < bpp; i++) ret.imageData[dst++] = imageData[src++];
					dst -= 2 * bpp;
				}
			}

			return ret;
		}
예제 #8
0
		/// <summary>
		/// Gets a subimage from the image.
		/// </summary>
		/// <returns>The sub image.</returns>
		/// <param name="x">The x coordinate.</param>
		/// <param name="y">The y coordinate.</param>
		/// <param name="w">The width.</param>
		/// <param name="h">The height.</param>
		public Image8i GetSubimage(uint x, uint y, uint w, uint h)
		{
			if (x >= Width || y >= Height) throw new ArgumentOutOfRangeException("x or y", "Out of image.");

			Image8i ret = new Image8i(w, h, ChannelFormat);
			ret.Draw(-(int)x, -(int)y, this);
			return ret;
		}
예제 #9
0
		/// <summary>
		/// Compare the specified compareImage with a threshold.
		/// Returns similartiy in percent (100 % == similar images)
		/// </summary>
		/// <param name="compareImage">Compare image.</param>
		/// <param name="threshold">Threshold.</param>
		public double Compare(Image8i compareImage, uint threshold)
		{
			if (compareImage == null) throw new Exception("Image is null");
			if (Width != compareImage.Width) throw new Exception("Image have different sizes");
			if (Height != compareImage.Height) throw new Exception("Image have different sizes");
			if (ChannelFormat != compareImage.ChannelFormat) throw new Exception("Image have different formats");

			uint divergency = 0;

			for (uint y = 0; y < Width; y++)
			{
				for (uint x = 0; x < Height; x++)
				{
					Color8i picA = GetPixel(x, y);
					Color8i picB = compareImage.GetPixel(x, y);

					int dif = 0;

					dif += System.Math.Abs(picA.R - picB.R);
					dif += System.Math.Abs(picA.G - picB.G);
					dif += System.Math.Abs(picA.B - picB.B);
					dif /= 3;

					if (dif > threshold) divergency++;
				}
			}
				
			return (double)(100 * (divergency / (double)(Width * Height)));
		}
예제 #10
0
		/// <summary>
		/// Draw the specified x, y and source.
		/// </summary>
		/// <param name="x">The x coordinate.</param>
		/// <param name="y">The y coordinate.</param>
		/// <param name="source">Source.</param>
		public void Draw(int x, int y, Image8i sourceImage)
		{
			if (x >= Width || y >= Height) throw new ArgumentOutOfRangeException("x or y", "Out of image.");
			if (x + sourceImage.Width < 0 || y + sourceImage.Height < 0) throw new ArgumentOutOfRangeException("x or y", "Out of image.");

			Image8i srcimg = sourceImage.ToChannelFormat(ChannelFormat);
			if (srcimg == null) return;

			uint bytePerPixel = GetBytePerPixelFromChannelFormat(ChannelFormat);

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

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

					byte* src__ = src_ + start;
					byte* dst__ = dst_ + x * bytePerPixel + start;

					uint sw = sourceImage.Width * bytePerPixel;
					uint dw = Width * bytePerPixel;

					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++) *dst++ = *src++;
					}
				}
			}
		}
예제 #11
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
		}
예제 #12
0
		unsafe Image8i ToDownsampledImageHorizontal(uint w)
		{
			if ((Width * Height) == 0) return new Image8i(0, 0, ChannelFormat);
			if (w == 0) return new Image8i(0, 0, ChannelFormat);

			if (Width > w && Width % w == 0) return ToReducedByImageHorizontal(Width / w);

			double delta = ((double)Width) / w;

			if (ChannelFormat == ChannelFormat.Gray)
			{
				Image8i ret = new Image8i(w, Height, ChannelFormat);
				if (ret.imageData == null) return ret;

				fixed(byte* _dst=ret.imageData, _src=imageData)
				{
					byte* dst = _dst;

					for (uint y = 0; y < Height; y++)
					{
						byte* src = _src + y * Width;

						for (uint x = 0; x < w; x++)
						{
							double deltax = x * delta;
							double dx = 1 - (deltax - ((uint)deltax));
							byte* s = src + ((uint)deltax);
							double deltasum = dx;

							double gsum = *(s++) * dx;

							while ((delta - deltasum) > 0.0001)
							{
								dx = delta - deltasum;
								if (dx >= 1)
								{
									deltasum += 1;
									gsum += *(s++);
								}
								else
								{
									gsum += *s * dx;
									break;
								}
							}

							*(dst++) = (byte)(gsum / delta + 0.5);
						}
					}
				}

				return ret;
			}

			if (ChannelFormat == ChannelFormat.RGB || ChannelFormat == ChannelFormat.BGR)
			{
				Image8i ret = new Image8i(w, Height, ChannelFormat);
				if (ret.imageData == null) return ret;

				fixed(byte* _dst=ret.imageData, _src=imageData)
				{
					byte* dst = _dst;
					uint wb = Width * 3;

					for (uint y = 0; y < Height; y++)
					{
						byte* src = _src + y * wb;

						for (uint x = 0; x < w; x++)
						{
							double deltax = x * delta;
							double dx = 1 - (deltax - ((uint)deltax));
							byte* s = src + ((uint)deltax) * 3;
							double deltasum = dx;

							double rsum = *(s++) * dx;
							double gsum = *(s++) * dx;
							double bsum = *(s++) * dx;

							while ((delta - deltasum) > 0.0001)
							{
								dx = delta - deltasum;
								if (dx >= 1)
								{
									deltasum += 1;
									rsum += *(s++);
									gsum += *(s++);
									bsum += *(s++);
								}
								else
								{
									rsum += *(s++) * dx;
									gsum += *(s++) * dx;
									bsum += *s * dx;
									break;
								}
							}

							*(dst++) = (byte)(rsum / delta + 0.5);
							*(dst++) = (byte)(gsum / delta + 0.5);
							*(dst++) = (byte)(bsum / delta + 0.5);
						}
					}
				}

				return ret;
			}

			if (ChannelFormat == ChannelFormat.RGBA || ChannelFormat == ChannelFormat.BGRA)
			{
				Image8i ret = new Image8i(w, Height, ChannelFormat);
				if (ret.imageData == null) return ret;

				fixed(byte* _dst=ret.imageData, _src=imageData)
				{
					byte* dst = _dst;
					uint wb = Width * 4;

					for (uint y = 0; y < Height; y++)
					{
						byte* src = _src + y * wb;

						for (uint x = 0; x < w; x++)
						{
							double deltax = x * delta;
							double dx = 1 - (deltax - ((uint)deltax));
							byte* s = src + ((uint)deltax) * 4;
							double deltasum = dx;

							byte r = *(s++), g = *(s++), b = *(s++);
							uint a = *(s++);

							double adx = a * dx;
							double rsum = r * adx;
							double gsum = g * adx;
							double bsum = b * adx;
							double asum = adx;

							while ((delta - deltasum) > 0.0001)
							{
								dx = delta - deltasum;
								r = *(s++);
								g = *(s++);
								b = *(s++);
								a = *(s++);
								if (dx >= 1)
								{
									deltasum += 1;
									rsum += r * a;
									gsum += g * a;
									bsum += b * a;
									asum += a;
								}
								else
								{
									adx = a * dx;
									rsum += r * adx;
									gsum += g * adx;
									bsum += b * adx;
									asum += adx;
									break;
								}
							}

							*(dst++) = (byte)(rsum / asum + 0.5);
							*(dst++) = (byte)(gsum / asum + 0.5);
							*(dst++) = (byte)(bsum / asum + 0.5);
							*(dst++) = (byte)(asum / delta + 0.5);
						}
					}
				}

				return ret;
			}

			if (ChannelFormat == ChannelFormat.GrayAlpha)
			{
				Image8i ret = new Image8i(w, Height, ChannelFormat);
				if (ret.imageData == null) return ret;

				fixed(byte* _dst=ret.imageData, _src=imageData)
				{
					byte* dst = _dst;
					uint wb = Width * 2;

					for (uint y = 0; y < Height; y++)
					{
						byte* src = _src + y * wb;

						for (uint x = 0; x < w; x++)
						{
							double deltax = x * delta;
							double dx = 1 - (deltax - ((uint)deltax));
							byte* s = src + ((uint)deltax) * 2;
							double deltasum = dx;

							byte g = *(s++);
							uint a = *(s++);

							double gsum = g * dx * a;
							double asum = a * dx;

							while ((delta - deltasum) > 0.0001)
							{
								dx = delta - deltasum;
								g = *(s++);
								a = *(s++);
								if (dx >= 1)
								{
									deltasum += 1;
									gsum += g * a;
									asum += a;
								}
								else
								{
									double adx = a * dx;
									gsum += g * adx;
									asum += adx;
									break;
								}
							}

							*(dst++) = (byte)(gsum / asum + 0.5);
							*(dst++) = (byte)(asum / delta + 0.5);
						}
					}
				}
				return ret;
			}

			return new Image8i(0, 0, ChannelFormat);
		}
예제 #13
0
		public static Image8i FromBitmap(Bitmap bmp)
		{
			Image8i ret = null;

			uint width = (uint)bmp.Width;
			uint height = (uint)bmp.Height;

			if ((bmp.PixelFormat & PixelFormat.Alpha) == PixelFormat.Alpha)
			{
				ret = new Image8i(width, height, ChannelFormat.RGBA);

				BitmapData data = bmp.LockBits(new Rectangle(0, 0, (int)width, (int)height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
				Marshal.Copy(data.Scan0, ret.imageData, 0, (int)(width * height * 4));
				bmp.UnlockBits(data);
			}
			else
			{
				ret = new Image8i(width, height, ChannelFormat.RGB);

				BitmapData data = bmp.LockBits(new Rectangle(0, 0, (int)width, (int)height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
				if (((int)width * 3) == data.Stride)
				{
					Marshal.Copy(data.Scan0, ret.imageData, 0, (int)(width * height * 3));
				}
				else
				{
					if (IntPtr.Size == 4)
					{
						for (uint i = 0; i < height; i++)
						{
							Marshal.Copy((IntPtr)(data.Scan0.ToInt32() + (int)(i * data.Stride)), ret.imageData, (int)(width * 3 * i), (int)(width * 3));
						}
					}
					else if (IntPtr.Size == 8)
					{
						for (uint i = 0; i < height; i++)
						{
							Marshal.Copy((IntPtr)(data.Scan0.ToInt64() + (long)(i * data.Stride)), ret.imageData, (int)(width * 3 * i), (int)(width * 3));
						}
					}
				}

				bmp.UnlockBits(data);
				data = null;
				bmp.Dispose();
				bmp = null;
			}

			return ret;
		}
예제 #14
0
		unsafe Image8i ToDownsampledImageVertical(uint h)
		{
			if ((Width * Height) == 0) return new Image8i(0, 0, ChannelFormat);
			if (h == 0) return new Image8i(0, 0, ChannelFormat);

			if (Height > h && Height % h == 0) return ToReducedByImageVertical(Height / h);
			double delta = ((double)Height) / h;

			if (ChannelFormat == ChannelFormat.Gray)
			{
				Image8i ret = new Image8i(Width, h, ChannelFormat);
				if (ret.imageData == null) return ret;

				for (uint x = 0; x < Width; x++)
				{
					fixed(byte* _dst=ret.imageData, _src=imageData)
					{
						byte* dst = _dst + x;
						byte* src = _src + x;

						for (uint y = 0; y < h; y++)
						{
							double deltay = y * delta;
							double dy = 1 - (deltay - ((uint)deltay));
							byte* s = src + ((uint)deltay) * Width;
							double deltasum = dy;

							double gsum = *s * dy;
							s += Width;

							while ((delta - deltasum) > 0.0001)
							{
								dy = delta - deltasum;
								if (dy >= 1)
								{
									deltasum += 1;
									gsum += *s;
									s += Width;
								}
								else
								{
									gsum += *s * dy;
									break;
								}
							}

							*dst = (byte)(gsum / delta + 0.5);
							dst += Width;
						}
					}
				}
				return ret;
			}

			if (ChannelFormat == ChannelFormat.RGB || ChannelFormat == ChannelFormat.BGR)
			{
				Image8i ret = new Image8i(Width, h, ChannelFormat);
				if (ret.imageData == null) return ret;

				int wb = (int)Width * 3;
				int wb2 = wb - 2;

				for (uint x = 0; x < Width; x++)
				{
					fixed(byte* _dst=ret.imageData, _src=imageData)
					{
						byte* dst = _dst + x * 3;
						byte* src = _src + x * 3;

						for (uint y = 0; y < h; y++)
						{
							double deltay = y * delta;
							double dy = 1 - (deltay - ((uint)deltay));
							byte* s = src + ((uint)deltay) * wb;
							double deltasum = dy;

							double rsum = *(s++) * dy;
							double gsum = *(s++) * dy;
							double bsum = *s * dy;
							s += wb2;

							while ((delta - deltasum) > 0.0001)
							{
								dy = delta - deltasum;
								if (dy >= 1)
								{
									deltasum += 1;
									rsum += *(s++);
									gsum += *(s++);
									bsum += *s;
									s += wb2;
								}
								else
								{
									rsum += *(s++) * dy;
									gsum += *(s++) * dy;
									bsum += *s * dy;
									break;
								}
							}

							*(dst++) = (byte)(rsum / delta + 0.5);
							*(dst++) = (byte)(gsum / delta + 0.5);
							*dst = (byte)(bsum / delta + 0.5);
							dst += wb2;
						}
					}
				}
				return ret;
			}

			if (ChannelFormat == ChannelFormat.RGBA || ChannelFormat == ChannelFormat.BGRA)
			{
				Image8i ret = new Image8i(Width, h, ChannelFormat);
				if (ret.imageData == null) return ret;

				int wb = (int)Width * 4;
				int wb3 = wb - 3;

				for (uint x = 0; x < Width; x++)
				{
					fixed(byte* _dst=ret.imageData, _src=imageData)
					{
						byte* dst = _dst + x * 4;
						byte* src = _src + x * 4;

						for (uint y = 0; y < h; y++)
						{
							double deltay = y * delta;
							double dy = 1 - (deltay - ((uint)deltay));
							byte* s = src + ((uint)deltay) * wb;
							double deltasum = dy;

							byte r = *(s++), g = *(s++), b = *(s++);
							uint a = *s;
							s += wb3;

							double ady = a * dy;
							double rsum = r * ady;
							double gsum = g * ady;
							double bsum = b * ady;
							double asum = ady;

							while ((delta - deltasum) > 0.0001)
							{
								r = *(s++);
								g = *(s++);
								b = *(s++);
								a = *s;
								s += wb3;

								dy = delta - deltasum;
								if (dy >= 1)
								{
									deltasum += 1;
									rsum += r * a;
									gsum += g * a;
									bsum += b * a;
									asum += a;
								}
								else
								{
									ady = a * dy;
									rsum += r * ady;
									gsum += g * ady;
									bsum += b * ady;
									asum += ady;
									break;
								}
							}

							*(dst++) = (byte)(rsum / asum + 0.5);
							*(dst++) = (byte)(gsum / asum + 0.5);
							*(dst++) = (byte)(bsum / asum + 0.5);
							*dst = (byte)(asum / delta + 0.5);
							dst += wb3;
						}
					}
				}

				return ret;
			}

			if (ChannelFormat == ChannelFormat.GrayAlpha)
			{
				Image8i ret = new Image8i(Width, h, ChannelFormat);
				if (ret.imageData == null) return ret;

				int wb = (int)Width * 2;
				int wb1 = wb - 1;

				for (uint x = 0; x < Width; x++)
				{
					fixed(byte* _dst=ret.imageData, _src=imageData)
					{
						byte* dst = _dst + x * 2;
						byte* src = _src + x * 2;

						for (uint y = 0; y < h; y++)
						{
							double deltay = y * delta;
							double dy = 1 - (deltay - ((uint)deltay));
							byte* s = src + ((uint)deltay) * wb;
							double deltasum = dy;

							byte g = *(s++);
							uint a = *s;
							s += wb1;

							double ady = a * dy;
							double gsum = g * ady;
							double asum = ady;

							while ((delta - deltasum) > 0.0001)
							{
								g = *(s++);
								a = *s;
								s += wb1;

								dy = delta - deltasum;
								if (dy >= 1)
								{
									deltasum += 1;
									gsum += g * a;
									asum += a;
								}
								else
								{
									ady = a * dy;
									gsum += g * ady;
									asum += ady;
									break;
								}
							}

							*(dst++) = (byte)(gsum / asum + 0.5);
							*dst = (byte)(asum / delta + 0.5);
							dst += wb1;
						}
					}
				}

				return ret;
			}

			return new Image8i(0, 0, ChannelFormat);
		}
예제 #15
0
		public Image8i ToFlippedImageHorizontal()
		{
			Image8i ret = new Image8i(Width, Height, ChannelFormat);
			if (ret.imageData == null) return ret;

			uint bw = Width * GetBytePerPixelFromChannelFormat(ChannelFormat);

			uint src = 0;
			uint dst = Height * bw;

			for (uint y = 0; y < Height; y++)
			{
				dst -= bw;
				for (uint x = 0; x < bw; x++) ret.imageData[dst++] = imageData[src++];
				dst -= bw;
			}

			return ret;
		}
예제 #16
0
		public Image8i ToAlphaInvertedImage()
		{
			if (ChannelFormat != ChannelFormat.RGBA && ChannelFormat != ChannelFormat.BGRA && ChannelFormat != ChannelFormat.GrayAlpha) return this;

			Image8i ret = new Image8i(Width, Height, ChannelFormat);
			if (ret.ImageData == null) return ret;

			uint count = Width * Height * GetBytePerPixelFromChannelFormat(ChannelFormat);

			if (ChannelFormat == ChannelFormat.BGRA || ChannelFormat == ChannelFormat.RGBA)
			{
				for (uint i = 0; i < count; i += 4)
				{
					ret.imageData[i] = (byte)(imageData[i]);
					ret.imageData[i + 1] = (byte)(imageData[i + 1]);
					ret.imageData[i + 2] = (byte)(imageData[i + 2]);
					ret.imageData[i + 3] = (byte)(255 - imageData[i + 3]);
				}
			}
			else if (ChannelFormat == ChannelFormat.GrayAlpha)
			{
				for (uint i = 0; i < count; i += 2)
				{
					ret.imageData[i] = (byte)(imageData[i]);
					ret.imageData[i + 1] = (byte)(255 - imageData[i + 1]);
				}
			}

			return ret;
		}
예제 #17
0
		public Image8i ToFlippedImageDiagonal()
		{
			Image8i ret = new Image8i(Height, Width, ChannelFormat);

			uint bpp = GetBytePerPixelFromChannelFormat(ChannelFormat);
			uint bw = Height * bpp;

			uint src = 0;
			uint dst = 0;

			for (uint y = 0; y < Height; y++)
			{
				for (uint x = 0; x < Width; x++)
				{
					for (uint i = 0; i < bpp; i++) ret.imageData[dst++] = imageData[src++];
					dst += bw - bpp;
				}
				dst = y * bpp;
			}

			return ret;
		}
예제 #18
0
		Image8i ToNearestPixelResizedImageVertical(uint h)
		{
			double delta = (double)Height / h;

			Image8i ret = new Image8i(Width, h, ChannelFormat);
			if (ret.imageData == null) return ret;

			uint bpp = GetBytePerPixelFromChannelFormat(ChannelFormat);
			uint bw = Width * bpp;

			uint dst = 0;

			for (uint y = 0; y < h; y++)
			{
				uint src = ((uint)(y * delta + delta / 2)) * bw;
				for (uint i = 0; i < bw; i++) ret.imageData[dst++] = imageData[src++];
			}

			return ret;
		}
예제 #19
0
		public Image8i To90DegreeRotatedImage()
		{
			Image8i ret = new Image8i(Height, Width, ChannelFormat);
			if (ret.imageData == null) return ret;

			uint bpp = GetBytePerPixelFromChannelFormat(ChannelFormat);
			uint bw = Height * bpp;

			uint src = 0;
			uint dst_ = (Width - 1) * bw;

			for (uint y = 0; y < Height; y++)
			{
				uint dst = dst_;
				for (uint x = 0; x < Width; x++)
				{
					for (uint i = 0; i < bpp; i++) ret.imageData[dst++] = imageData[src++];
					dst -= bw + bpp;
				}
				dst_ += bpp;
			}

			return ret;
		}
예제 #20
0
		Image8i ToNearestPixelResizedImageHorizontal(uint w)
		{
			double delta = (double)Width / w;

			uint bpp = GetBytePerPixelFromChannelFormat(ChannelFormat);

			uint[] dx = new uint[w];
			for (uint x = 0; x < w; x++) dx[x] = (uint)(x * delta + delta / 2);

			if (bpp == 1)
			{
				Image8i ret = new Image8i(w, Height, ChannelFormat);
				if (ret.imageData == null) return ret;

				uint dst = 0;

				for (uint y = 0; y < Height; y++)
				{
					uint src = y * Width;
					for (uint x = 0; x < w; x++) ret.imageData[dst++] = imageData[src + dx[x]];
				}

				return ret;
			}

			if (bpp == 4)
			{
				Image8i ret = new Image8i(w, Height, ChannelFormat);
				if (ret.imageData == null) return ret;

				uint bw = Width * 4;
				uint dst = 0;

				for (uint y = 0; y < Height; y++)
				{
					uint src = y * bw;

					for (uint x = 0; x < w; x++)
					{
						uint s = src + dx[x] * 4;
						ret.imageData[dst++] = imageData[s++];
						ret.imageData[dst++] = imageData[s++];
						ret.imageData[dst++] = imageData[s++];
						ret.imageData[dst++] = imageData[s];
					}
				}

				return ret;
			}

			if (bpp == 3)
			{
				Image8i ret = new Image8i(w, Height, ChannelFormat);
				if (ret.imageData == null) return ret;

				uint bw = Width * 3;
				uint dst = 0;

				for (uint y = 0; y < Height; y++)
				{
					uint src = y * bw;

					for (uint x = 0; x < w; x++)
					{
						uint s = src + dx[x] * 3;
						ret.imageData[dst++] = imageData[s++];
						ret.imageData[dst++] = imageData[s++];
						ret.imageData[dst++] = imageData[s];
					}
				}

				return ret;
			}

			if (bpp == 2)
			{
				Image8i ret = new Image8i(w, Height, ChannelFormat);
				if (ret.imageData == null) return ret;

				uint bw = Width * 2;
				uint dst = 0;

				for (uint y = 0; y < Height; y++)
				{
					uint src = y * bw;

					for (uint x = 0; x < w; x++)
					{
						uint s = src + dx[x] * 2;
						ret.imageData[dst++] = imageData[s++];
						ret.imageData[dst++] = imageData[s];
					}
				}

				return ret;
			}

			return new Image8i(0, 0, ChannelFormat);
		}
예제 #21
0
		public Image8i To270DegreeRotatedImage()
		{
			Image8i ret = new Image8i(Height, Width, ChannelFormat);
			if (ret.imageData == null) return ret;

			uint bpp = GetBytePerPixelFromChannelFormat(ChannelFormat);
			uint bw = Width * bpp;

			uint dst = 0;
			uint src_ = (Height - 1) * bw;

			for (uint y = 0; y < Width; y++)
			{
				uint src = src_;
				for (uint x = 0; x < Height; x++)
				{
					for (uint i = 0; i < bpp; i++) ret.imageData[dst++] = imageData[src++];
					src -= bw + bpp;
				}
				src_ += bpp;
			}

			return ret;
		}
예제 #22
0
		Image8i ToNearestPixelResizedImageVerticalHorizontal(uint w, uint h)
		{
			double deltah = (double)Height / h;
			double deltaw = (double)Width / w;

			uint bpp = GetBytePerPixelFromChannelFormat(ChannelFormat);

			uint[] dx = new uint[w];
			for (uint x = 0; x < w; x++) dx[x] = (uint)(x * deltaw + deltaw / 2);

			if (bpp == 1)
			{
				Image8i ret = new Image8i(w, h, ChannelFormat);
				if (ret.imageData == null) return ret;

				uint dst = 0;

				for (uint y = 0; y < h; y++)
				{
					uint src = (uint)(y * deltah + deltah / 2) * Width;
					for (uint x = 0; x < w; x++) ret.imageData[dst++] = imageData[src + dx[x]];
				}

				return ret;
			}

			if (bpp == 4)
			{
				Image8i ret = new Image8i(w, h, ChannelFormat);
				if (ret.imageData == null) return ret;

				uint dst = 0;
				uint w4 = Width * 4;

				for (uint y = 0; y < h; y++)
				{
					uint src = (uint)(y * deltah + deltah / 2) * w4;

					for (uint x = 0; x < w; x++)
					{
						uint s = src + dx[x] * 4;
						ret.imageData[dst++] = imageData[s++];
						ret.imageData[dst++] = imageData[s++];
						ret.imageData[dst++] = imageData[s++];
						ret.imageData[dst++] = imageData[s];
					}
				}

				return ret;
			}

			if (bpp == 3)
			{
				Image8i ret = new Image8i(w, h, ChannelFormat);
				if (ret.imageData == null) return ret;

				uint dst = 0;
				uint w3 = Width * 3;

				for (uint y = 0; y < h; y++)
				{
					uint src = (uint)(y * deltah + deltah / 2) * w3;

					for (uint x = 0; x < w; x++)
					{
						uint s = src + dx[x] * 3;
						ret.imageData[dst++] = imageData[s++];
						ret.imageData[dst++] = imageData[s++];
						ret.imageData[dst++] = imageData[s];
					}
				}

				return ret;
			}

			if (bpp == 2)
			{
				Image8i ret = new Image8i(w, h, ChannelFormat);
				if (ret.imageData == null) return ret;

				uint dst = 0;
				uint w2 = Width * 2;

				for (uint y = 0; y < h; y++)
				{
					uint src = (uint)(y * deltah + deltah / 2) * w2;

					for (uint x = 0; x < w; x++)
					{
						uint s = src + dx[x] * 2;
						ret.imageData[dst++] = imageData[s++];
						ret.imageData[dst++] = imageData[s];
					}
				}

				return ret;
			}

			return new Image8i(0, 0, ChannelFormat);
		}
예제 #23
0
		/// <summary>
		/// Swaps the channels to GBR;
		/// </summary>
		/// <returns>The channels to GB.</returns>
		public Image8i ToGBRSwappedChannels()
		{
			if (ChannelFormat != ChannelFormat.RGB) return this.ToChannelFormatRGB().ToBGRSwappedChannels();
			Image8i ret = new Image8i(Width, Height, ChannelFormat.RGB);
			if (ret.imageData == null) return ret;

			uint count = Width * Height;
			byte[] src = imageData;
			uint ind = 0;
			byte[] dst = ret.imageData;
			uint inds = 0;

			// Channel Swap RGB
			for (uint i = 0; i < count; i++)
			{
				byte r = src[inds++];
				byte g = src[inds++];
				byte b = src[inds++];
				dst[ind++] = g;
				dst[ind++] = b;
				dst[ind++] = r;
			}

			return ret;
		}
예제 #24
0
		public static void ToFile(string filename, Image8i image)
		{
			if (filename == null) throw new Exception();
			if (filename == "") throw new Exception();
			if (image.Width == 0 || image.Height == 0) throw new Exception();
			if (image.Width > 0xFFFF || image.Height > 0xFFFF) throw new Exception();

			if (image.ChannelFormat == ChannelFormat.BGR)
			{
				ToFile(filename, image.ToChannelFormatRGB());
				return;
			}

			if (image.ChannelFormat == ChannelFormat.BGRA)
			{
				ToFile(filename, image.ToChannelFormatRGBA());
				return;
			}

			bool isRGB = (image.ChannelFormat == ChannelFormat.BGR || image.ChannelFormat == ChannelFormat.RGB || image.ChannelFormat == ChannelFormat.BGRA || image.ChannelFormat == ChannelFormat.RGBA);
			bool isAlpha = (image.ChannelFormat == ChannelFormat.BGRA || image.ChannelFormat == ChannelFormat.RGBA || image.ChannelFormat == ChannelFormat.GrayAlpha);

			ulong size = (ulong)(18 + ((isRGB) ? (isAlpha ? 4 : 3) : (isAlpha ? 2 : 1)) * image.Width * image.Height); // Length of data
			if (size > 0xFFFFFFFF) throw new Exception(); // image is to big

			using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
			{
				BinaryWriter bw = new BinaryWriter(fs);

				byte Pixel_Depth = (byte)(isRGB ? (isAlpha ? 32 : 24) : (isAlpha ? 16 : 8));
				byte Image_Descriptor = (byte)(isAlpha ? 0x28 : 0x20);	// Field 5.6

				// Write header (18 bytes)
				bw.Write((byte)0);					// ID_Length
				bw.Write((byte)0);					// Color_Map_Type
				bw.Write((byte)(isRGB ? 2 : 3));	// Image_Type
				bw.Write((ushort)0);				// First_Entry_Index
				bw.Write((ushort)0);				// Color_Map_Length
				bw.Write((byte)0);					// Color_Map_Entry_Size
				bw.Write((ushort)0);				// X_Origin
				bw.Write((ushort)0);				// Y_Origin
				bw.Write((ushort)image.Width);		// Width
				bw.Write((ushort)image.Height);		// Height
				bw.Write(Pixel_Depth);				// Pixel_Depth
				bw.Write(Image_Descriptor);			// Image_Descriptor

				bw.Write(image.ImageData);
				bw.Close();
				fs.Close();
			}
		}