/// <see cref="ASCIICharHolder.GetClosestChar(uint)"/> public override IChars GetClosestChar(uint intensity) { ASCIIChar retVal = asciiChars[0] as ASCIIChar; int lowerBound = 0; int upperBound = asciiChars.Length - 1; while (lowerBound <= upperBound) { int index = lowerBound + (upperBound - lowerBound) / 2; retVal = (ASCIIChar)asciiChars[index]; if (retVal.fullIntensity == intensity) { return(retVal); } if (retVal.fullIntensity < intensity) { lowerBound = index + 1; } else { upperBound = index - 1; } } return(retVal); }
/// <summary> /// Defines CompareTo method since it derives from ICOmparable /// </summary> /// <param name="obj">Object to compare against</param> /// <returns>Result of comparison of fullIntensity</returns> public int CompareTo(object obj) { if (obj == null) { return(1); } ASCIIChar otherChar = obj as ASCIIChar; if (otherChar != null) { return(this.fullIntensity.CompareTo(otherChar.fullIntensity)); } else { throw new ArgumentException("Object passed to comparison is not ASCIIChar object"); } }
/// <summary> /// Converts given image to ascii_art. /// </summary> /// <param name="img">Image that will be converted</param> /// <param name="font">Font of ascii_art image. Also determines width and height of conversion matrix</param> /// <param name="holder">Appropriate holder for converting this image</param> /// <param name="colorConversion"><see cref="Converter.Convert(Font, Image, string,bool)"/></param> /// <returns>Image covnerted to ascii_art</returns> private Image ConvertToASCII(Bitmap img, Font font, ASCIICharHolder holder, bool colorConversion) { Bitmap retBmp = new Bitmap(img.Width, img.Height, PixelFormat.Format24bppRgb); int width = (int)font.Size; int height = font.Height; PixelFormat iFormat = img.PixelFormat; unsafe { BitmapData srcData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, iFormat); BitmapData dstData = retBmp.LockBits(new Rectangle(0, 0, retBmp.Width, retBmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); BitmapData origSrcData = originalImg.LockBits(new Rectangle(0, 0, originalImg.Width, originalImg.Height), ImageLockMode.ReadOnly, iFormat); int dataSrcBytesPerPixel = Image.GetPixelFormatSize(iFormat) / 8; int dataDstBytesPerPixel = Image.GetPixelFormatSize(PixelFormat.Format24bppRgb) / 8; byte *srcPointer, asciiPointer, dstPointer, orgPointer; Point leftUpperCorner = new Point(0, 0); for (int imgY = 0; imgY < img.Height; imgY += height) { for (int imgX = 0; imgX < img.Width; imgX += width) { uint aRed = 0, aGreen = 0, aBlue = 0; Bitmap asciiRestrictedBmp = new Bitmap(width, height, PixelFormat.Format24bppRgb); BitmapData asciiData = asciiRestrictedBmp.LockBits(new Rectangle(0, 0, asciiRestrictedBmp.Width, asciiRestrictedBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { srcPointer = (byte *)srcData.Scan0 + (y + imgY) * srcData.Stride + (x + imgX) * dataSrcBytesPerPixel; orgPointer = (byte *)origSrcData.Scan0 + (y + imgY) * origSrcData.Stride + (x + imgX) * dataSrcBytesPerPixel; asciiPointer = (byte *)asciiData.Scan0 + y * asciiData.Stride + x * dataDstBytesPerPixel; asciiPointer[0] = srcPointer[0]; asciiPointer[1] = srcPointer[1]; asciiPointer[2] = srcPointer[2]; aBlue += orgPointer[0]; aGreen += orgPointer[1]; aRed += orgPointer[2]; } } asciiRestrictedBmp.UnlockBits(asciiData); ASCIIChar asciiChar = new ASCIIChar(asciiRestrictedBmp); Bitmap asciiCharBmp = holder.GetClosestChar(asciiChar.fullIntensity).bmp; PixelFormat iFormat2 = asciiCharBmp.PixelFormat; int dataAsciiBytesPerPixel = Image.GetPixelFormatSize(iFormat2) / 8; BitmapData asciiBmpData = asciiCharBmp.LockBits(new Rectangle(0, 0, asciiCharBmp.Width, asciiCharBmp.Height), ImageLockMode.ReadOnly, iFormat); if (colorConversion) { aBlue /= (uint)(width * height); aGreen /= (uint)(width * height); aRed /= (uint)(width * height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { dstPointer = (byte *)dstData.Scan0 + (y + imgY) * dstData.Stride + (x + imgX) * dataDstBytesPerPixel; asciiPointer = (byte *)asciiBmpData.Scan0 + y * asciiBmpData.Stride + x * dataAsciiBytesPerPixel; dstPointer[0] = (asciiPointer[0] < 255) ? (byte)aBlue : (byte)255; dstPointer[1] = (asciiPointer[1] < 255) ? (byte)aGreen : (byte)255; dstPointer[2] = (asciiPointer[2] < 255) ? (byte)aRed : (byte)255; } } } else { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { dstPointer = (byte *)dstData.Scan0 + (y + imgY) * dstData.Stride + (x + imgX) * dataDstBytesPerPixel; asciiPointer = (byte *)asciiBmpData.Scan0 + y * asciiBmpData.Stride + x * dataAsciiBytesPerPixel; dstPointer[0] = asciiPointer[0]; dstPointer[1] = asciiPointer[1]; dstPointer[2] = asciiPointer[2]; } } } asciiCharBmp.UnlockBits(asciiBmpData); leftUpperCorner.X += width; if ((imgX + (width * 2) > img.Width) && (imgX + width != img.Width)) { imgX = img.Width - (width * 2); leftUpperCorner.X = img.Width - width; } } leftUpperCorner.Y += height; leftUpperCorner.X = 0; if ((imgY + (height * 2) >= img.Height) && (imgY + height != img.Height)) { imgY = img.Height - (height * 2); leftUpperCorner.Y = img.Height - height; } } retBmp.UnlockBits(dstData); img.UnlockBits(srcData); originalImg.UnlockBits(origSrcData); } return(retBmp); }