/// <see cref="ImageConverter.ConvertSelectedArea(Font, Image, string, bool)"/> public override Image ConvertSelectedArea(Font font, Image img, string subset, bool colorConversion) { ASCIICharHolder holder = GetAppropriateHolder(font, subset); try { int x0 = Math.Min(Form1.rectStartPoint.X, Form1.rectEndPoint.X); int y0 = Math.Min(Form1.rectStartPoint.Y, Form1.rectEndPoint.Y); int width = Math.Abs(Form1.rectStartPoint.X - Form1.rectEndPoint.X); int height = Math.Abs(Form1.rectStartPoint.Y - Form1.rectEndPoint.Y); if (font.Size > width || font.Height > height) { return(img); } Rectangle cloneRect = new Rectangle(x0, y0, width, height); Image convertPartImage = ((Bitmap)img).Clone(cloneRect, img.PixelFormat); ImageGrayScaler imgProcesser = new ImageGrayScaler((Bitmap)convertPartImage); originalImg = (Bitmap)convertPartImage; convertPartImage = imgProcesser.ConvertToGrayScale(); convertPartImage = ConvertToASCII((Bitmap)convertPartImage, font, holder, colorConversion); using (Graphics g = Graphics.FromImage(img)) { g.DrawImage(convertPartImage, cloneRect); } return(img); } catch (Exception) { throw new Exception("Image conversion failed"); } }
/// <see cref="ImageConverter.ConvertFullImage(Font, Image, string, bool)"/> public override Image ConvertFullImage(Font font, Image img, string subset, bool colorConversion) { ImageGrayScaler imgProcesser = new ImageGrayScaler((Bitmap)img); originalImg = (Bitmap)img; img = imgProcesser.ConvertToGrayScale(); ASCIICharHolder holder = GetAppropriateHolder(font, subset); try { return(ConvertToASCII((Bitmap)img, font, holder, colorConversion)); } catch (Exception) { throw new Exception("Image conversion failed"); } }
/// <summary> /// Based on given font and subset returns appropriate ASCIICharHolder /// </summary> /// <param name="font">font of desired holder</param> /// <param name="subset">string subset of desired holder</param> /// <returns>Appropriate holder with given font and subset</returns> ASCIICharHolder GetAppropriateHolder(Font font, string subset) { ASCIICharHolder holder = null; if ((holder = charHolders.Find(x => x.Equals(font, subset))) == null) { if (subset == null) { holder = new FullASCIICharHolder(font); } else { holder = new FixedASCIICharHolder(font, subset); } charHolders.Add(holder); } return(holder); }
/// <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); }