public void RenderScanline( IImageReaderWriter dest, ScanlineRasterizer sclineRas, Scanline scline, Color color) { #if DEBUG int dbugMinScanlineCount = 0; #endif //1. ensure single line buffer width _grayScaleLine.EnsureLineStride(dest.Width + 4); //2. setup vars byte[] dest_buffer = dest.GetBuffer(); int dest_w = dest.Width; int dest_h = dest.Height; int dest_stride = dest.Stride; int src_w = dest_w; int src_stride = dest_stride; //*** set color before call Blend() this._color = color; byte color_alpha = color.alpha; //--------------------------- //3. loop, render single scanline with subpixel rendering byte[] lineBuff = _grayScaleLine.GetInternalBuffer(); while (sclineRas.SweepScanline(scline)) { //3.1. clear _grayScaleLine.Clear(); //3.2. write grayscale span to temp buffer //3.3 convert to subpixel value and write to dest buffer //render solid single scanline int num_spans = scline.SpanCount; byte[] covers = scline.GetCovers(); //render each span in the scanline for (int i = 1; i <= num_spans; ++i) { ScanlineSpan span = scline.GetSpan(i); if (span.len > 0) { //positive len _grayScaleLine.SubPixBlendSolidHSpan(span.x, span.len, color_alpha, covers, span.cover_index); } else { //fill the line, same coverage area int x = span.x; int x2 = (x - span.len - 1); _grayScaleLine.SubPixBlendHL(x, x2, color_alpha, covers[span.cover_index]); } } BlendScanline(dest_buffer, dest_stride, scline.Y, src_w, src_stride, lineBuff); #if DEBUG dbugMinScanlineCount++; #endif } }
public AlphaMaskAdaptor(IImageReaderWriter image, IAlphaMask mask) : base(image) { linkedImage = image; m_mask = mask; m_spans = new byte[256]; }
protected override void CustomRenderSingleScanLine(IImageReaderWriter destImage, Scanline scanline, Color color) { int y = scanline.Y; int num_spans = scanline.SpanCount; byte[] covers = scanline.GetCovers(); int spanCount = scanline.SpanCount; var ras = gfx.ScanlineRasterizer; var rasToBmp = gfx.ScanlineRasToDestBitmap; for (int i = 1; i <= num_spans; ++i) { var span2 = scanline.GetSpan(i); int x = span2.x; int num_pix = span2.len; int coverIndex = span2.cover_index; do { int a = (covers[coverIndex++] * color.Alpha0To255) >> 8; m_square.Draw(rasToBmp, ras, m_sl, destImage, Color.FromArgb(a, color), x, y); ++x; }while (--num_pix > 0); } }
protected virtual void CustomRenderSingleScanLine( IImageReaderWriter dest, Scanline scline, ColorRGBA color) { //implement }
public void Sharpen(IImageReaderWriter img, int radius) { unsafe { TempMemPtr bufferPtr = img.GetBufferPtr(); int[] output = new int[bufferPtr.LengthInBytes / 4]; //TODO: review here again fixed(int *outputPtr = &output[0]) { byte *srcBuffer = (byte *)bufferPtr.Ptr; int * srcBuffer1 = (int *)srcBuffer; int * outputBuffer1 = (int *)outputPtr; int stride = img.Stride; int w = img.Width; int h = img.Height; MemHolder srcMemHolder = new MemHolder((IntPtr)srcBuffer1, bufferPtr.LengthInBytes / 4);// Surface srcSurface = new Surface(stride, w, h, srcMemHolder); // MemHolder destMemHolder = new MemHolder((IntPtr)outputPtr, bufferPtr.LengthInBytes / 4); Surface destSurface = new Surface(stride, w, h, destMemHolder); // SharpenRenderer shRenderer1 = new SharpenRenderer(); shRenderer1.Amount = radius; shRenderer1.Render(srcSurface, destSurface, new PixelFarm.Drawing.Rectangle[] { new PixelFarm.Drawing.Rectangle(0, 0, w, h) }, 0, 1); } bufferPtr.Release(); //ActualImage.SaveImgBufferToPngFile(output, img.Stride, img.Width + 1, img.Height + 1, "d:\\WImageTest\\test_1.png"); img.ReplaceBuffer(output); } }
//--------------------------------------------------------------------- public OutlineRenderer(IImageReaderWriter destImage, IPixelBlender destPixelBlender, LineProfileAnitAlias profile) { destImageSurface = destImage; lineProfile = profile; clippingRectangle = new RectInt(0, 0, 0, 0); doClipping = false; this.destPixelBlender = destPixelBlender; }
void Attach(IImageReaderWriter imgRW) { this.imgRW = imgRW; m_buffer = imgRW.GetBuffer(); m_src_width = imgRW.Width; m_src_height = imgRW.Height; m_distanceBetweenPixelsInclusive = imgRW.BytesBetweenPixelsInclusive; }
//-------------------------------------------------------------------- public ImgSpanGenRGB_BilinearClip(IImageReaderWriter src, ColorRGBA back_color, ISpanInterpolator inter) : base(inter) { m_bgcolor = back_color; srcRW = (ImageReaderWriterBase)src; }
//-------------------------------------------------------------------- public ImgSpanGenRGB_BilinearClip(IImageReaderWriter src, Drawing.Color back_color, ISpanInterpolator inter) : base(inter) { m_bgcolor = back_color; srcRW = (ImageReaderWriterBase)src; }
public void RenderWithColor(IImageReaderWriter dest, ScanlineRasterizer sclineRas, Scanline scline, Color color) { if (!sclineRas.RewindScanlines()) { return; } //early exit //----------------------------------------------- scline.ResetSpans(sclineRas.MinX, sclineRas.MaxX); switch (this.ScanlineRenderMode) { default: { while (sclineRas.SweepScanline(scline)) { //render solid single scanline int y = scline.Y; int num_spans = scline.SpanCount; byte[] covers = scline.GetCovers(); //render each span in the scanline for (int i = 1; i <= num_spans; ++i) { ScanlineSpan span = scline.GetSpan(i); if (span.len > 0) { //positive len dest.BlendSolidHSpan(span.x, y, span.len, color, covers, span.cover_index); } else { //fill the line, same coverage area int x = span.x; int x2 = (x - span.len - 1); dest.BlendHL(x, y, x2, color, covers[span.cover_index]); } } } } break; case Agg.ScanlineRenderMode.SubPixelRendering: { scSubPixRas.RenderScanline(dest, sclineRas, scline, color); } break; case Agg.ScanlineRenderMode.Custom: { while (sclineRas.SweepScanline(scline)) { CustomRenderSingleScanLine(dest, scline, color); } } break; } }
//--------------------------------------------------------------------- //typedef renderer_outline_image<BaseRenderer, ImagePattern> self_type; //--------------------------------------------------------------------- public ImageLineRenderer(IImageReaderWriter ren, LineImagePattern patt) { m_ren = ren; m_pattern = patt; m_start = (0); m_scale_x = (1.0); m_clip_box = new RectInt(0, 0, 0, 0); m_clipping = (false); }
public ChildImage(IImageReaderWriter image, IPixelBlender blender, int distanceBetweenPixelsInclusive, int bufferOffset, int bitsPerPixel) { SetRecieveBlender(blender); Attach(image, blender, distanceBetweenPixelsInclusive, bufferOffset, bitsPerPixel); }
public ImgSpanGenRGBA_BilinearClip(IImageReaderWriter src, Drawing.Color back_color, ISpanInterpolator inter) : base(inter) { m_bgcolor = back_color; srcRW = (ImageReaderWriterBase)src; bytesBetweenPixelInclusive = srcRW.BytesBetweenPixelsInclusive; }
public ImgSpanGenGray_NNStepXby1(IImageReaderWriter src, ISpanInterpolator spanInterpolator) : base(spanInterpolator) { srcRW = (ImageReaderWriterBase)src; if (srcRW.BitDepth != 8) { throw new NotSupportedException("The source is expected to be 32 bit."); } }
public ImgSpanGenRGBA_BilinearClip(IImageReaderWriter src, ColorRGBA back_color, ISpanInterpolator inter) : base(inter) { m_bgcolor = back_color; srcRW = (ImageReaderWriterBase)src; bytesBetweenPixelInclusive = srcRW.BytesBetweenPixelsInclusive; }
public SubImageRW(IImageReaderWriter image, IPixelBlender blender, int distanceBetweenPixelsInclusive, int arrayOffset32, int bitsPerPixel) { SetRecieveBlender(blender); Attach(image, blender, distanceBetweenPixelsInclusive, arrayOffset32, bitsPerPixel); }
//-------------------------------------------------------------------- public FilterRGBAImageSpanGen(IImageReaderWriter src, ISpanInterpolator inter, ImageFilterLookUpTable filter) : base(src, inter, filter) { if (src.GetRecieveBlender().NumPixelBits != 32) { throw new System.FormatException("You have to use a rgba blender with span_image_resample_rgba"); } }
//-------------------------------------------------------------------- public FilterRGBImageSpanGen(IImageReaderWriter src, ISpanInterpolator inter, ImageFilterLookUpTable filter) : base(src, inter, filter) { if (src.GetRecieveBlender().NumPixelBits != 24) { throw new System.FormatException("You have to use a rgb blender with span_image_resample_rgb"); } }
public void RenderWithSpan(IImageReaderWriter dest, ScanlineRasterizer sclineRas, Scanline scline, ISpanGenerator spanGenerator) { if (!sclineRas.RewindScanlines()) { return; } //early exit //----------------------------------------------- scline.ResetSpans(sclineRas.MinX, sclineRas.MaxX); spanGenerator.Prepare(); if (dest.Stride / 4 > (tempSpanColors.AllocatedSize)) { //if not enough -> alloc more tempSpanColors.Clear(dest.Stride / 4); } ColorRGBA[] colorArray = tempSpanColors.Array; while (sclineRas.SweepScanline(scline)) { //render single scanline int y = scline.Y; int num_spans = scline.SpanCount; byte[] covers = scline.GetCovers(); for (int i = 1; i <= num_spans; ++i) { ScanlineSpan span = scline.GetSpan(i); int x = span.x; int span_len = span.len; bool firstCoverForAll = false; if (span_len < 0) { span_len = -span_len; firstCoverForAll = true; } //make absolute value //1. generate colors -> store in colorArray spanGenerator.GenerateColors(colorArray, 0, x, y, span_len); //2. blend color in colorArray to destination image dest.BlendColorHSpan(x, y, span_len, colorArray, 0, covers, span.cover_index, firstCoverForAll); } } }
public FilterImageSpanGenerator(IImageReaderWriter src, ISpanInterpolator inter, ImageFilterLookUpTable filterLookup) : base(inter) { this.imageBufferAccessor = new ImageBufferAccessor(src); m_scale_limit = 20; //m_blur_x = ((int)img_subpix_scale.SCALE); //m_blur_y = ((int)img_subpix_scale.SCALE); this.filterLookup = filterLookup; }
int bufferOffset; // the beggining of the image in this buffer public ChildImage(IImageReaderWriter image, int bufferOffsetToFirstPixel, int width, int height) { SetRecieveBlender(image.GetRecieveBlender()); AttachBuffer(image.GetBuffer(), bufferOffsetToFirstPixel, width, height, image.Stride, image.BitDepth, image.BytesBetweenPixelsInclusive); }
public void Draw( ScanlineRasToDestBitmapRenderer sclineRasToBmp, ScanlineRasterizer ras, Scanline sl, IImageReaderWriter destImage, ColorRGBA color, double x, double y) { ras.Reset(); ras.MoveTo(x * m_size, y * m_size); ras.LineTo(x * m_size + m_size, y * m_size); ras.LineTo(x * m_size + m_size, y * m_size + m_size); ras.LineTo(x * m_size, y * m_size + m_size); sclineRasToBmp.RenderWithColor(destImage, ras, sl, color); }
public SubImageRW(IImageReaderWriter image, int arrayOffset32, int width, int height) { SetRecieveBlender(image.GetRecieveBlender()); AttachBuffer(image.GetInt32Buffer(), arrayOffset32, width, height, image.Stride, image.BitDepth, image.BytesBetweenPixelsInclusive); }
public void Render(IImageReaderWriter source, AffinePlan[] affinePlans) { VertexStore tmpImgBoundVxs = GetFreeVxs(); Affine destRectTransform = BuildImageBoundsPath(source.Width, source.Height, tmpImgBoundVxs, affinePlans); // We invert it because it is the transform to make the image go to the same position as the polygon. LBB [2/24/2004] Affine sourceRectTransform = destRectTransform.CreateInvert(); var imgSpanGen = new ImgSpanGenRGBA_BilinearClip( source, ColorRGBA.Black, new SpanInterpolatorLinear(sourceRectTransform)); Render(destRectTransform.TransformToVxs(tmpImgBoundVxs), imgSpanGen); ReleaseVxs(tmpImgBoundVxs); }
/// <summary> /// This will create a new ImageBuffer that references the same memory as the image that you took the sub image from. /// It will modify the original main image when you draw to it. /// </summary> /// <param name="parentImage"></param> /// <param name="childImageBounds"></param> /// <returns></returns> public static ChildImage CreateChildImage(IImageReaderWriter parentImage, RectInt childImageBounds) { if (childImageBounds.Left < 0 || childImageBounds.Bottom < 0 || childImageBounds.Right > parentImage.Width || childImageBounds.Top > parentImage.Height || childImageBounds.Left >= childImageBounds.Right || childImageBounds.Bottom >= childImageBounds.Top) { throw new ArgumentException("The subImageBounds must be on the image and valid."); } int left = Math.Max(0, childImageBounds.Left); int bottom = Math.Max(0, childImageBounds.Bottom); int width = Math.Min(parentImage.Width - left, childImageBounds.Width); int height = Math.Min(parentImage.Height - bottom, childImageBounds.Height); int bufferOffsetToFirstPixel = parentImage.GetBufferOffsetXY(left, bottom); return new ChildImage(parentImage, bufferOffsetToFirstPixel, width, height); }
Affine BuildImageBoundsPath(IImageReaderWriter sourceImage, VertexStore drawImageRectPath, AffinePlan[] affPlans) { int srcW = sourceImage.Width; int srcH = sourceImage.Height; drawImageRectPath.Clear(); drawImageRectPath.AddMoveTo(0, 0); drawImageRectPath.AddLineTo(srcW, 0); drawImageRectPath.AddLineTo(srcW, srcH); drawImageRectPath.AddLineTo(0, srcH); drawImageRectPath.AddCloseFigure(); return(Affine.NewMatix(affPlans)); }
Affine BuildImageBoundsPath(IImageReaderWriter sourceImage, VertexStore drawImageRectPath, double destX, double destY, double hotspotOffsetX, double hotSpotOffsetY, double scaleX, double scaleY, double angleRad) { AffinePlan[] plan = new AffinePlan[4]; int i = 0; if (hotspotOffsetX != 0.0f || hotSpotOffsetY != 0.0f) { plan[i] = AffinePlan.Translate(-hotspotOffsetX, -hotSpotOffsetY); i++; } if (scaleX != 1 || scaleY != 1) { plan[i] = AffinePlan.Scale(scaleX, scaleY); i++; } if (angleRad != 0) { plan[i] = AffinePlan.Rotate(angleRad); i++; } if (destX != 0 || destY != 0) { plan[i] = AffinePlan.Translate(destX, destY); i++; } int srcW = sourceImage.Width; int srcH = sourceImage.Height; drawImageRectPath.Clear(); drawImageRectPath.AddMoveTo(0, 0); drawImageRectPath.AddLineTo(srcW, 0); drawImageRectPath.AddLineTo(srcW, srcH); drawImageRectPath.AddLineTo(0, srcH); drawImageRectPath.AddCloseFigure(); return(Affine.NewMatix(plan)); }
/// <summary> /// This will create a new ImageBuffer that references the same memory as the image that you took the sub image from. /// It will modify the original main image when you draw to it. /// </summary> /// <param name="parentImage"></param> /// <param name="subImgBounds"></param> /// <returns></returns> public static SubImageRW CreateSubImgRW(IImageReaderWriter parentImage, RectInt subImgBounds) { if (subImgBounds.Left < 0 || subImgBounds.Bottom < 0 || subImgBounds.Right > parentImage.Width || subImgBounds.Top > parentImage.Height || subImgBounds.Left >= subImgBounds.Right || subImgBounds.Bottom >= subImgBounds.Top) { throw new ArgumentException("The subImageBounds must be on the image and valid."); } int left = Math.Max(0, subImgBounds.Left); int bottom = Math.Max(0, subImgBounds.Bottom); int width = Math.Min(parentImage.Width - left, subImgBounds.Width); int height = Math.Min(parentImage.Height - bottom, subImgBounds.Height); int bufferOffsetToFirstPixel = parentImage.GetByteBufferOffsetXY(left, bottom); return(new SubImageRW(parentImage, bufferOffsetToFirstPixel / 4, width, height)); }
public static void RenderSolidAllPaths(this ScanlineRasToDestBitmapRenderer sclineRasToBmp, IImageReaderWriter destImage, ScanlineRasterizer sclineRas, Scanline scline, VertexStore vxs, Drawing.Color[] colors, int[] path_id, int num_paths) { for (int i = 0; i < num_paths; ++i) { sclineRas.Reset(); sclineRas.AddPath(new VertexStoreSnap(vxs, path_id[i])); sclineRasToBmp.RenderWithColor(destImage, sclineRas, scline, colors[i]); } }
/// <summary> /// This will create a new ImageBuffer that references the same memory as the image that you took the sub image from. /// It will modify the original main image when you draw to it. /// </summary> /// <param name="parentImage"></param> /// <param name="childImageBounds"></param> /// <returns></returns> public static ChildImage CreateChildImage(IImageReaderWriter parentImage, RectInt childImageBounds) { if (childImageBounds.Left < 0 || childImageBounds.Bottom < 0 || childImageBounds.Right > parentImage.Width || childImageBounds.Top > parentImage.Height || childImageBounds.Left >= childImageBounds.Right || childImageBounds.Bottom >= childImageBounds.Top) { throw new ArgumentException("The subImageBounds must be on the image and valid."); } int left = Math.Max(0, childImageBounds.Left); int bottom = Math.Max(0, childImageBounds.Bottom); int width = Math.Min(parentImage.Width - left, childImageBounds.Width); int height = Math.Min(parentImage.Height - bottom, childImageBounds.Height); int bufferOffsetToFirstPixel = parentImage.GetBufferOffsetXY(left, bottom); return(new ChildImage(parentImage, bufferOffsetToFirstPixel, width, height)); }
public void Render(IImageReaderWriter source, AffinePlan[] affinePlans) { VertexStore v1 = GetFreeVxs(); Affine destRectTransform = BuildImageBoundsPath(source.Width, source.Height, affinePlans, v1); // We invert it because it is the transform to make the image go to the same position as the polygon. LBB [2/24/2004] Affine sourceRectTransform = destRectTransform.CreateInvert(); var imgSpanGen = new ImgSpanGenRGBA_BilinearClip( source, Drawing.Color.Transparent, new SpanInterpolatorLinear(sourceRectTransform)); VertexStore v2 = destRectTransform.TransformToVxs(v1, GetFreeVxs()); Render(v2, imgSpanGen); // ReleaseVxs(ref v1); ReleaseVxs(ref v2); }
void Attach(IImageReaderWriter sourceImage, IPixelBlender recieveBlender, int distanceBetweenPixelsInclusive, int bufferOffset, int bitsPerPixel) { SetDimmensionAndFormat(sourceImage.Width, sourceImage.Height, sourceImage.Stride, bitsPerPixel, distanceBetweenPixelsInclusive); int offset = sourceImage.GetBufferOffsetXY(0, 0); byte[] buffer = sourceImage.GetBuffer(); SetBuffer(buffer, offset + bufferOffset); SetRecieveBlender(recieveBlender); }
public override void CopyFrom(IImageReaderWriter sourceImage, RectInt sourceImageRect, int destXOffset, int destYOffset) { RectInt destRect = sourceImageRect; destRect.Offset(destXOffset, destYOffset); RectInt clippedSourceRect = new RectInt(); if (clippedSourceRect.IntersectRectangles(destRect, m_ClippingRect)) { // move it back relative to the source clippedSourceRect.Offset(-destXOffset, -destYOffset); base.CopyFrom(sourceImage, clippedSourceRect, destXOffset, destYOffset); } }
void Attach(IImageReaderWriter sourceImage, IPixelBlender recieveBlender, int distanceBetweenPixelsInclusive, int arrayElemOffset, int bitsPerPixel) { _sourceImage = sourceImage; SetDimmensionAndFormat(sourceImage.Width, sourceImage.Height, sourceImage.Stride, bitsPerPixel, distanceBetweenPixelsInclusive); int srcOffset32 = sourceImage.GetByteBufferOffsetXY(0, 0) / 4; int[] buffer = sourceImage.GetInt32Buffer(); SetBuffer(buffer, srcOffset32 + arrayElemOffset); SetRecieveBlender(recieveBlender); }
public void AttachImage(IImageReaderWriter image) { linkedImage = image; }
protected virtual void CustomRenderSingleScanLine( IImageReaderWriter dest, Scanline scline, Color color) { //implement }
//public static readonly int cover_shift = 8; //public static readonly int cover_none = 0; //public static readonly int cover_full = 255; public AlphaMaskByteClipped(IImageReaderWriter rbuf, uint step, uint offset) { m_Step = step; m_Offset = offset; m_rbuf = rbuf; }
public void BlurX(IImageReaderWriter img, double radius) { if (radius < 0.62) return; if (img.Width < 3) return; double s = (double)(radius * 0.5); double q = (double)((s < 2.5) ? 3.97156 - 4.14554 * Math.Sqrt(1 - 0.26891 * s) : 0.98711 * s - 0.96330); double q2 = (double)(q * q); double q3 = (double)(q2 * q); double b0 = (double)(1.0 / (1.578250 + 2.444130 * q + 1.428100 * q2 + 0.422205 * q3)); double b1 = (double)(2.44413 * q + 2.85619 * q2 + 1.26661 * q3); double b2 = (double)(-1.42810 * q2 + -1.26661 * q3); double b3 = (double)(0.422205 * q3); double b = (double)(1 - (b1 + b2 + b3) * b0); b1 *= b0; b2 *= b0; b3 *= b0; int w = img.Width; int h = img.Height; int wm = (int)w - 1; int x, y; int startCreatingAt = (int)m_sum1.Count; m_sum1.AdjustSize(w); m_sum2.AdjustSize(w); m_buf.Allocate(w); RecursizeBlurCalculator[] Sum1Array = m_sum1.Array; RecursizeBlurCalculator[] Sum2Array = m_sum2.Array; Color[] BufferArray = m_buf.Array; for (int i = startCreatingAt; i < w; i++) { Sum1Array[i] = m_RecursizeBlurCalculatorFactory.CreateNew(); Sum2Array[i] = m_RecursizeBlurCalculatorFactory.CreateNew(); } for (y = 0; y < h; y++) { RecursizeBlurCalculator c = m_RecursizeBlurCalculatorFactory; c.FromPix(img.GetPixel(0, y)); Sum1Array[0].Calc(b, b1, b2, b3, c, c, c, c); c.FromPix(img.GetPixel(1, y)); Sum1Array[1].Calc(b, b1, b2, b3, c, Sum1Array[0], Sum1Array[0], Sum1Array[0]); c.FromPix(img.GetPixel(2, y)); Sum1Array[2].Calc(b, b1, b2, b3, c, Sum1Array[1], Sum1Array[0], Sum1Array[0]); for (x = 3; x < w; ++x) { c.FromPix(img.GetPixel(x, y)); Sum1Array[x].Calc(b, b1, b2, b3, c, Sum1Array[x - 1], Sum1Array[x - 2], Sum1Array[x - 3]); } Sum2Array[wm].Calc(b, b1, b2, b3, Sum1Array[wm], Sum1Array[wm], Sum1Array[wm], Sum1Array[wm]); Sum2Array[wm - 1].Calc(b, b1, b2, b3, Sum1Array[wm - 1], Sum2Array[wm], Sum2Array[wm], Sum2Array[wm]); Sum2Array[wm - 2].Calc(b, b1, b2, b3, Sum1Array[wm - 2], Sum2Array[wm - 1], Sum2Array[wm], Sum2Array[wm]); Sum2Array[wm].ToPix(ref BufferArray[wm]); Sum2Array[wm - 1].ToPix(ref BufferArray[wm - 1]); Sum2Array[wm - 2].ToPix(ref BufferArray[wm - 2]); for (x = wm - 3; x >= 0; --x) { Sum2Array[x].Calc(b, b1, b2, b3, Sum1Array[x], Sum2Array[x + 1], Sum2Array[x + 2], Sum2Array[x + 3]); Sum2Array[x].ToPix(ref BufferArray[x]); } img.CopyColorHSpan(0, y, w, BufferArray, 0); } }
public void Blur(IImageReaderWriter img, double radius) { BlurX(img, radius); BlurY(img, radius); }
public void BlurY(IImageReaderWriter img, double radius) { FormatTransposer img2 = new FormatTransposer(img); BlurX(img2, radius); }
//public static readonly int cover_shift = 8; //public static readonly int cover_none = 0; //public static readonly int cover_full = 255; public AlphaMaskByteUnclipped(IImageReaderWriter rbuf, uint Step, uint Offset) { m_Step = Step; m_Offset = Offset; m_rbuf = rbuf; }
public void Render(IImageReaderWriter source, AffinePlan[] affinePlans) { VertexStore v1 = GetFreeVxs(); Affine destRectTransform = BuildImageBoundsPath(source.Width, source.Height, v1, affinePlans); // We invert it because it is the transform to make the image go to the same position as the polygon. LBB [2/24/2004] Affine sourceRectTransform = destRectTransform.CreateInvert(); var imgSpanGen = new ImgSpanGenRGBA_BilinearClip( source, Drawing.Color.Black, new SpanInterpolatorLinear(sourceRectTransform)); var v2 = destRectTransform.TransformToVxs(v1, GetFreeVxs()); Render(v2, imgSpanGen); // ReleaseVxs(ref v1); ReleaseVxs(ref v2); }
public void attach(IImageReaderWriter rbuf) { m_rbuf = rbuf; }
public void RenderWithSpan(IImageReaderWriter dest, ScanlineRasterizer sclineRas, Scanline scline, ISpanGenerator spanGenerator) { if (!sclineRas.RewindScanlines()) { return; } //early exit //----------------------------------------------- scline.ResetSpans(sclineRas.MinX, sclineRas.MaxX); spanGenerator.Prepare(); if (dest.Stride / 4 > (tempSpanColors.AllocatedSize)) { //if not enough -> alloc more tempSpanColors.Clear(dest.Stride / 4); } Color[] colorArray = tempSpanColors.Array; while (sclineRas.SweepScanline(scline)) { //render single scanline int y = scline.Y; int num_spans = scline.SpanCount; byte[] covers = scline.GetCovers(); for (int i = 1; i <= num_spans; ++i) { ScanlineSpan span = scline.GetSpan(i); int x = span.x; int span_len = span.len; bool firstCoverForAll = false; if (span_len < 0) { span_len = -span_len; firstCoverForAll = true; } //make absolute value //1. generate colors -> store in colorArray spanGenerator.GenerateColors(colorArray, 0, x, y, span_len); //2. blend color in colorArray to destination image dest.BlendColorHSpan(x, y, span_len, colorArray, 0, covers, span.cover_index, firstCoverForAll); } } }
public void RenderWithColor(IImageReaderWriter dest, ScanlineRasterizer sclineRas, Scanline scline, Color color) { if (!sclineRas.RewindScanlines()) { return; } //early exit //----------------------------------------------- scline.ResetSpans(sclineRas.MinX, sclineRas.MaxX); switch (this.ScanlineRenderMode) { default: { //prev mode //this mode while (sclineRas.SweepScanline(scline)) { //render solid single scanline int y = scline.Y; int num_spans = scline.SpanCount; byte[] covers = scline.GetCovers(); //render each span in the scanline for (int i = 1; i <= num_spans; ++i) { ScanlineSpan span = scline.GetSpan(i); if (span.len > 0) { //positive len dest.BlendSolidHSpan(span.x, y, span.len, color, covers, span.cover_index); } else { //fill the line, same coverage area int x = span.x; int x2 = (x - span.len - 1); dest.BlendHL(x, y, x2, color, covers[span.cover_index]); } } } } break; case Agg.ScanlineRenderMode.SubPixelRendering: { #if DEBUG int dbugMinScanlineCount = 0; #endif while (sclineRas.SweepScanline(scline)) { SubPixRender(dest, scline, color); #if DEBUG dbugMinScanlineCount++; #endif } } break; case Agg.ScanlineRenderMode.Custom: { while (sclineRas.SweepScanline(scline)) { CustomRenderSingleScanLine(dest, scline, color); } } break; } }
public virtual void CopyFrom(IImageReaderWriter sourceImage, RectInt sourceImageRect, int destXOffset, int destYOffset) { linkedImage.CopyFrom(sourceImage, sourceImageRect, destXOffset, destYOffset); }
public ChildImage(IImageReaderWriter image, IPixelBlender blender, int x1, int y1, int x2, int y2) { SetRecieveBlender(blender); Attach(image, x1, y1, x2, y2); }
void SubPixRender(IImageReaderWriter dest, Scanline scanline, Color color) { byte[] covers = scanline.GetCovers(); int num_spans = scanline.SpanCount; int y = scanline.Y; byte[] buffer = dest.GetBuffer(); IPixelBlender blender = dest.GetRecieveBlender(); int last_x = int.MinValue; int bufferOffset = 0; //------------------------------------------ Color bgColor = Color.White; float cb_R = bgColor.R / 255f; float cb_G = bgColor.G / 255f; float cb_B = bgColor.B / 255f; float cf_R = color.R / 255f; float cf_G = color.G / 255f; float cf_B = color.B / 255f; //------------------------------------------ int prevCover = -1; for (int i = 1; i <= num_spans; ++i) { //render span by span ScanlineSpan span = scanline.GetSpan(i); if (span.x != last_x + 1) { bufferOffset = dest.GetBufferOffsetXY(span.x, y); } last_x = span.x; int num_pix = span.len; if (num_pix < 0) { //special encode*** num_pix = -num_pix; //make it positive value last_x += (num_pix - 1); //long span with coverage int coverageValue = covers[span.cover_index]; //------------------------------------------- if (coverageValue >= 255) { //100% cover int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; Color todrawColor = Color.FromArgb(a, Color.FromArgb(color.R, color.G, color.B)); while (num_pix > 0) { blender.BlendPixel(buffer, bufferOffset, todrawColor); bufferOffset += 4; //1 pixel 4 bytes --num_pix; } } else { int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; Color newc = Color.FromArgb(color.R, color.G, color.B); Color todrawColor = Color.FromArgb(a, newc); while (num_pix > 0) { blender.BlendPixel(buffer, bufferOffset, todrawColor); bufferOffset += 4; //1 pixel 4 bytes --num_pix; } } prevCover = coverageValue; } else { int coverIndex = span.cover_index; last_x += (num_pix - 1); while (num_pix > 0) { int coverageValue = covers[coverIndex++]; if (coverageValue >= 255) { //100% cover Color newc = Color.FromArgb(color.R, color.G, color.B); int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, Color.FromArgb(a, newc)); prevCover = coverageValue; } else { //check direction : bool isUpHill = coverageValue >= prevCover; //if (isUpHill != ((coverageValue % 2) > 0)) //{ //} //---------------------------- byte c_r = 0, c_g = 0, c_b = 0; //---------------------------- //assume lcd screen is RGB float subpix_percent = ((float)(coverageValue) / 256f); if (coverageValue < cover_1_3) { //assume LCD color arrangement is BGR if (isUpHill) { c_r = bgColor.R; c_g = bgColor.G; c_b = (byte)(mix(cb_B, cf_B, subpix_percent) * 255); } else { c_r = (byte)(mix(cb_R, cf_R, subpix_percent) * 255); c_g = bgColor.G; c_b = bgColor.B; } int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, Color.FromArgb(a, Color.FromArgb(c_r, c_g, c_b))); } else if (coverageValue < cover_2_3) { if (isUpHill) { c_r = bgColor.R; c_g = (byte)(mix(cb_G, cf_G, subpix_percent) * 255); c_b = (byte)(mix(cb_B, cf_B, 1) * 255); } else { c_r = (byte)(mix(cb_R, cf_R, 1) * 255); c_g = (byte)(mix(cb_G, cf_G, subpix_percent) * 255); c_b = bgColor.B; } int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, Color.FromArgb(a, Color.FromArgb(c_r, c_g, c_b))); } else { //cover > 2/3 but not full if (isUpHill) { c_r = (byte)(mix(cb_R, cf_R, subpix_percent) * 255); c_g = (byte)(mix(cb_G, cf_G, 1) * 255); c_b = (byte)(mix(cb_B, cf_B, 1) * 255); } else { c_r = (byte)(mix(cb_R, cf_R, 1) * 255); c_g = (byte)(mix(cb_G, cf_G, 1) * 255); c_b = (byte)(mix(cb_B, cf_B, subpix_percent) * 255); } int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, Color.FromArgb(a, Color.FromArgb(c_r, c_g, c_b))); } } bufferOffset += 4; //1 pixel 4 bits --num_pix; prevCover = coverageValue; } } } }
public ChildImage(IImageReaderWriter image, IPixelBlender blender) { Attach(image, blender, image.BytesBetweenPixelsInclusive, 0, image.BitDepth); }
public ProxyImage(IImageReaderWriter linkedImage) { this.linkedImage = linkedImage; }
public FormatTransposer(IImageReaderWriter pixelFormat) : base(pixelFormat) { }
public void Render(IImageReaderWriter source, double destX, double destY) { int inScaleX = 1; int inScaleY = 1; int angleRadians = 0; // exit early if the dest and source bounds don't touch. // TODO: <BUG> make this do rotation and scalling RectInt sourceBounds = source.GetBounds(); RectInt destBounds = this.destImageReaderWriter.GetBounds(); sourceBounds.Offset((int)destX, (int)destY); if (!RectInt.DoIntersect(sourceBounds, destBounds)) { //if (inScaleX != 1 || inScaleY != 1 || angleRadians != 0) //{ // throw new NotImplementedException(); //} return; } double scaleX = inScaleX; double scaleY = inScaleY; Affine graphicsTransform = this.CurrentTransformMatrix; if (!graphicsTransform.IsIdentity()) { if (scaleX != 1 || scaleY != 1 || angleRadians != 0) { throw new NotImplementedException(); } graphicsTransform.Transform(ref destX, ref destY); } #if false // this is an optomization that eliminates the drawing of images that have their alpha set to all 0 (happens with generated images like explosions). MaxAlphaFrameProperty maxAlphaFrameProperty = MaxAlphaFrameProperty::GetMaxAlphaFrameProperty(source); if((maxAlphaFrameProperty.GetMaxAlpha() * color.A_Byte) / 256 <= ALPHA_CHANNEL_BITS_DIVISOR) { m_OutFinalBlitBounds.SetRect(0,0,0,0); } #endif bool isScale = (scaleX != 1 || scaleY != 1); bool isRotated = true; if (Math.Abs(angleRadians) < (0.1 * MathHelper.Tau / 360)) { isRotated = false; angleRadians = 0; } //bool IsMipped = false; //double ox, oy; //source.GetOriginOffset(out ox, out oy); bool canUseMipMaps = isScale; if (scaleX > 0.5 || scaleY > 0.5) { canUseMipMaps = false; } bool needSourceResampling = isScale || isRotated || destX != (int)destX || destY != (int)destY; VertexStore imgBoundsPath = GetFreeVxs(); // this is the fast drawing path if (needSourceResampling) { #if false // if the scalling is small enough the results can be improved by using mip maps if(CanUseMipMaps) { CMipMapFrameProperty* pMipMapFrameProperty = CMipMapFrameProperty::GetMipMapFrameProperty(source); double OldScaleX = scaleX; double OldScaleY = scaleY; const CFrameInterface* pMippedFrame = pMipMapFrameProperty.GetMipMapFrame(ref scaleX, ref scaleY); if(pMippedFrame != source) { IsMipped = true; source = pMippedFrame; sourceOriginOffsetX *= (OldScaleX / scaleX); sourceOriginOffsetY *= (OldScaleY / scaleY); } HotspotOffsetX *= (inScaleX / scaleX); HotspotOffsetY *= (inScaleY / scaleY); } #endif Affine destRectTransform = BuildImageBoundsPath(source.Width, source.Height, imgBoundsPath, destX, destY, ox, oy, scaleX, scaleY, angleRadians); // We invert it because it is the transform to make the image go to the same position as the polygon. LBB [2/24/2004] Affine sourceRectTransform = destRectTransform.CreateInvert(); var imgSpanGen = new ImgSpanGenRGBA_BilinearClip( source, Drawing.Color.Black, new SpanInterpolatorLinear(sourceRectTransform)); var v1 = destRectTransform.TransformToVxs(imgBoundsPath, GetFreeVxs()); Render(v1, imgSpanGen); ReleaseVxs(ref v1); #if false // this is some debug you can enable to visualize the dest bounding box LineFloat(BoundingRect.left, BoundingRect.top, BoundingRect.right, BoundingRect.top, WHITE); LineFloat(BoundingRect.right, BoundingRect.top, BoundingRect.right, BoundingRect.bottom, WHITE); LineFloat(BoundingRect.right, BoundingRect.bottom, BoundingRect.left, BoundingRect.bottom, WHITE); LineFloat(BoundingRect.left, BoundingRect.bottom, BoundingRect.left, BoundingRect.top, WHITE); #endif } else // TODO: this can be even faster if we do not use an intermediat buffer { Affine destRectTransform = BuildImageBoundsPath(source.Width, source.Height, imgBoundsPath, destX, destY); // We invert it because it is the transform to make the image go to the same position as the polygon. LBB [2/24/2004] Affine sourceRectTransform = destRectTransform.CreateInvert(); var interpolator = new SpanInterpolatorLinear(sourceRectTransform); ImgSpanGen imgSpanGen = null; switch (source.BitDepth) { case 32: imgSpanGen = new ImgSpanGenRGBA_NN_StepXBy1(source, interpolator); break; case 24: imgSpanGen = new ImgSpanGenRGB_NNStepXby1(source, interpolator); break; case 8: imgSpanGen = new ImgSpanGenGray_NNStepXby1(source, interpolator); break; default: throw new NotImplementedException(); } var v1 = destRectTransform.TransformToVxs(imgBoundsPath, GetFreeVxs()); Render(v1, imgSpanGen); ReleaseVxs(ref v1); unchecked { destImageChanged++; }; } ReleaseVxs(ref imgBoundsPath); }