internal override void CopyPixels(TempMemPtr dstBuffer, int arrayOffset, Color srcColor, int count) { unsafe { unchecked { int *ptr = (int *)dstBuffer.Ptr + arrayOffset; { //TODO: consider use memcpy() impl*** int argb = srcColor.ToARGB(); //--------- if ((count % 2) != 0) { *ptr = argb; ptr++; //move next count--; } while (count > 0) { //----------- //1. *ptr = argb; ptr++; //move next count--; //----------- //2 *ptr = argb; ptr++; //move next count--; } } } } }
public static int[] CopyImgBuffer(this MemBitmap memBmp, int width, int height) { //calculate stride for the width int destStride = MemBitmap.CalculateStride(width, PixelFormat.ARGB32); int newBmpW = destStride / 4; int[] buff2 = new int[newBmpW * height]; unsafe { using (TempMemPtr srcBufferPtr = MemBitmap.GetBufferPtr(memBmp)) { byte *srcBuffer = (byte *)srcBufferPtr.Ptr; int srcIndex = 0; int srcStride = memBmp.Stride; fixed(int *destHead = &buff2[0]) { byte *destHead2 = (byte *)destHead; for (int line = 0; line < height; ++line) { //System.Runtime.InteropServices.Marshal.Copy(srcBuffer, srcIndex, (IntPtr)destHead2, destStride); MemMx.memcpy((byte *)destHead2, srcBuffer + srcIndex, destStride); srcIndex += srcStride; destHead2 += destStride; } } } } return(buff2); }
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); } }
/// <summary> /// attach image buffer and its information to the reader /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="bitsPerPixel"></param> /// <param name="imgbuffer"></param> /// <param name="outputPxBlender"></param> protected void Attach(int width, int height, int bitsPerPixel, TempMemPtr imgbuffer, PixelBlender32 outputPxBlender) { if (width <= 0 || height <= 0) { throw new ArgumentOutOfRangeException("You must have a width and height > than 0."); } if (bitsPerPixel != 32 && bitsPerPixel != 24 && bitsPerPixel != 8) { throw new Exception("Unsupported bits per pixel."); } // // int bytesPerPixel = (bitsPerPixel + 7) / 8; int stride = 4 * ((width * bytesPerPixel + 3) / 4); #if DEBUG if (bytesPerPixel == 0) { } #endif // SetDimmensionAndFormat(width, height, stride, bitsPerPixel, bitsPerPixel / 8); SetUpLookupTables(); OutputPixelBlender = outputPxBlender; _raw_buffer32 = imgbuffer.Ptr; _rawBufferLenInBytes = imgbuffer.LengthInBytes; }
public override void Apply() { unsafe { using (TempMemPtr bufferPtr = _target.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 = _target.Stride; int w = _target.Width; int h = _target.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); // _shRenderer1.Amount = Radius; _shRenderer1.Render(srcSurface, destSurface, new PixelFarm.Drawing.Rectangle[] { new PixelFarm.Drawing.Rectangle(0, 0, w, h) }, 0, 1); } _target.WriteBuffer(output); } } }
public static void CopyFromGdiPlusBitmapSameSize( Bitmap windowsBitmap, ActualImage actualImage) { int h = windowsBitmap.Height; int w = windowsBitmap.Width; //byte[] targetBuffer = ActualImage.GetBuffer(actualImage); BitmapData bitmapData1 = windowsBitmap.LockBits( new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadWrite, windowsBitmap.PixelFormat); IntPtr scan0 = bitmapData1.Scan0; int stride = bitmapData1.Stride; //TODO: review here //use buffer copy unsafe { TempMemPtr targetPtr = ActualImage.GetBufferPtr(actualImage); //target int startRowAt = ((h - 1) * stride); byte *src = (byte *)scan0; byte *targetBuffer = (byte *)targetPtr.Ptr; for (int y = h; y > 0; --y) { // byte* target = targetH + ((y - 1) * stride); //System.Runtime.InteropServices.Marshal.Copy( // (IntPtr)src,//src // targetBuffer, startRowAt, stride); AggMemMx.memcpy(targetBuffer + startRowAt, src, stride); startRowAt -= stride; src += stride; } ////////////////////////////////////////////////////////////////// //fixed (byte* targetH = &targetBuffer[0]) //{ // byte* src = (byte*)scan0; // for (int y = h; y > 0; --y) // { // byte* target = targetH + ((y - 1) * stride); // for (int n = stride - 1; n >= 0; --n) // { // *target = *src; // target++; // src++; // } // } //} } windowsBitmap.UnlockBits(bitmapData1); }
internal override void BlendPixels(TempMemPtr dstBuffer, int arrayOffset, Color srcColor) { unsafe { //fixed (int* head = &dstBuffer[arrayOffset]) BlendPixel32Internal((int *)dstBuffer.Ptr + arrayOffset, srcColor); } }
public void SetImageAttributes(LoadedImageAttributes parameters) { _imgWidth = parameters.Width; _imgHeight = parameters.Height; _component = parameters.Components; _bitStream = new BitStream(); _memBmp = new MemBitmap(_imgWidth, _imgHeight); _tempMemPtr = MemBitmap.GetBufferPtr(_memBmp); }
public override void SetClipboardImage(Image img) { if (img is MemBitmap memBmp) { System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(memBmp.Width, memBmp.Height); using (TempMemPtr tmp = MemBitmap.GetBufferPtr(memBmp)) { BitmapHelper.CopyToGdiPlusBitmapSameSize(tmp.Ptr, bmp); } } }
void BlendScanline(ActualImage destImg, byte[] expandGreyBuffer, PixelFarm.Drawing.Color color, int x, int y, int width) { byte[] rgb = new byte[3] { color.R, color.G, color.B }; //------------------------- //destination TempMemPtr memPtr = ActualImage.GetBufferPtr(destImg); //start pixel int destImgIndex = (x * 4) + (destImg.Stride * y); //start img src int srcImgIndex = x + (width * y); int colorIndex = 0; int round = 0; byte color_a = color.alpha; unsafe { byte *destImgBuffer = (byte *)memPtr.Ptr; while (width > 3) { int a0 = expandGreyBuffer[srcImgIndex] * color_a; int a1 = expandGreyBuffer[srcImgIndex + 1] * color_a; int a2 = expandGreyBuffer[srcImgIndex + 2] * color_a; byte ec0 = destImgBuffer[destImgIndex]; //existing color byte ec1 = destImgBuffer[destImgIndex + 1]; //existing color byte ec2 = destImgBuffer[destImgIndex + 2]; //existing color //------------------------------------------------------ //please note that we swap a2 and a0 on the fly**** //------------------------------------------------------ byte n0 = (byte)((((rgb[colorIndex] - ec0) * a2) + (ec0 << 16)) >> 16); byte n1 = (byte)((((rgb[colorIndex + 1] - ec1) * a1) + (ec1 << 16)) >> 16); byte n2 = (byte)((((rgb[colorIndex + 2] - ec2) * a0) + (ec2 << 16)) >> 16); destImgBuffer[destImgIndex] = n0; destImgBuffer[destImgIndex + 1] = n1; destImgBuffer[destImgIndex + 2] = n2; destImgIndex += 4; round = 0; colorIndex = 0; srcImgIndex += 3; width -= 3; } memPtr.Release(); } }
static byte[] CreateGreyScaleBuffer(ActualImage img) { //assume img is 32 rgba img int imgW = img.Width; int height = img.Height; //56 level grey scale buffer TempMemPtr srcMemPtr = ActualImage.GetBufferPtr(img); int greyScaleBufferLen = imgW * height; byte[] greyScaleBuffer = new byte[greyScaleBufferLen]; int destIndex = 0; int srcImgIndex = 0; int srcImgStride = img.Stride; unsafe { byte *srcImgBuffer = (byte *)srcMemPtr.Ptr; for (int y = 0; y < height; ++y) { srcImgIndex = srcImgStride * y; destIndex = imgW * y; for (int x = 0; x < imgW; ++x) { byte r = srcImgBuffer[srcImgIndex]; byte g = srcImgBuffer[srcImgIndex + 1]; byte b = srcImgBuffer[srcImgIndex + 2]; byte a = srcImgBuffer[srcImgIndex + 3]; if (r != 0 || g != 0 || b != 0) { } if (a != 255) { } //skip alpha //byte greyScaleValue = // (byte)((0.333f * (float)r) + (0.5f * (float)g) + (0.1666f * (float)b)); greyScaleBuffer[destIndex] = (byte)(((a + 1) / 256f) * 64f); destIndex++; srcImgIndex += 4; } } } srcMemPtr.Release(); return(greyScaleBuffer); }
void AttachBuffer(TempMemPtr buffer, int elemOffset, int width, int height, int strideInBytes, int bitDepth, int distanceInBytesBetweenPixelsInclusive) { SetBufferToNull(); SetDimmensionAndFormat(width, height, strideInBytes, bitDepth, distanceInBytesBetweenPixelsInclusive); SetBuffer(buffer, elemOffset); }
public SubBitmapBlender(TempMemPtr buffer, int arrayOffset32, int width, int height, int strideInBytes, int bitDepth, int distanceInBytesBetweenPixelsInclusive) { AttachBuffer(buffer, arrayOffset32, width, height, strideInBytes, bitDepth, distanceInBytesBetweenPixelsInclusive); }
/// <summary> /// copy from actual image direct to hBmpScan0 /// </summary> /// <param name="actualImage"></param> /// <param name="hBmpScan0"></param> public static void CopyToWindowsBitmapSameSize( ActualImage actualImage, IntPtr hBmpScan0) { //1st, fast //byte[] rawBuffer = ActualImage.GetBuffer(actualImage); unsafe { TempMemPtr memPtr = ActualImage.GetBufferPtr(actualImage); AggMemMx.memcpy((byte *)hBmpScan0, (byte *)memPtr.Ptr, actualImage.Stride * actualImage.Height); memPtr.Release(); } //System.Runtime.InteropServices.Marshal.Copy(rawBuffer, 0, // hBmpScan0, rawBuffer.Length); }
internal override void CopyPixel(TempMemPtr dstBuffer, int arrayOffset, Color srcColor) { //copy single pixel unsafe { //int* dstBuff = (int*)dstBuffer.Ptr; int *ptr = (int *)dstBuffer.Ptr + arrayOffset; { //TODO: consider use memcpy() impl*** *ptr = srcColor.ToARGB(); } } // throw new NotImplementedException(); }
public static int[] CopyImgBuffer(MemBitmap memBmp) { int[] buff2 = new int[memBmp.Width * memBmp.Height]; unsafe { using (TempMemPtr pixBuffer = MemBitmap.GetBufferPtr(memBmp)) { //fixed (byte* header = &pixelBuffer[0]) byte *header = (byte *)pixBuffer.Ptr; { System.Runtime.InteropServices.Marshal.Copy((IntPtr)header, buff2, 0, buff2.Length);//length in bytes } } } return(buff2); }
public override void GenerateColors(Drawing.Color[] outputColors, int startIndex, int x, int y, int len) { if (_noTransformation) { //Interpolator.GetCoord(out int x_hr, out int y_hr); //int x_lr = x_hr >> subpix_const.SHIFT; //int y_lr = y_hr >> subpix_const.SHIFT; Interpolator.SubPixTranslateBeginCoord(x + dx, y + dy, out int x_lr, out int y_lr); NN_StepXBy1(_bmpSrc, _bmpSrc.GetBufferOffsetXY32(x_lr, y_lr), outputColors, startIndex, len); } else { ISpanInterpolator spanInterpolator = Interpolator; spanInterpolator.Begin(x + dx, y + dy, len); unsafe { using (TempMemPtr.FromBmp(_bmpSrc, out int *srcBuffer)) { //TODO: if no any transformation,=> skip spanInterpolator (see above example) do { //spanInterpolator.GetCoord(out int x_hr, out int y_hr); //int x_lr = x_hr >> subpix_const.SHIFT; //int y_lr = y_hr >> subpix_const.SHIFT; spanInterpolator.SubPixGetTranslatedCoord(out int x_lr, out int y_lr); int bufferIndex = _bmpSrc.GetBufferOffsetXY32(x_lr, y_lr); int srcColor = srcBuffer[bufferIndex++]; outputColors[startIndex] = Drawing.Color.FromArgb( (srcColor >> CO.A_SHIFT) & 0xff, //a (srcColor >> CO.R_SHIFT) & 0xff, //r (srcColor >> CO.G_SHIFT) & 0xff, //g (srcColor >> CO.B_SHIFT) & 0xff); //b ++startIndex; spanInterpolator.Next(); } while (--len != 0); } } } }
//bool Attach(IBitmapBlender sourceImage, int x1, int y1, int x2, int y2) //{ // _sourceImage = sourceImage; // SetBufferToNull(); // if (x1 > x2 || y1 > y2) // { // throw new Exception("You need to have your x1 and y1 be the lower left corner of your sub image."); // } // RectInt boundsRect = new RectInt(x1, y1, x2, y2); // if (boundsRect.Clip(new RectInt(0, 0, sourceImage.Width - 1, sourceImage.Height - 1))) // { // SetDimmensionAndFormat(boundsRect.Width, boundsRect.Height, sourceImage.Stride, sourceImage.BitDepth, sourceImage.BytesBetweenPixelsInclusive); // int bufferOffset = sourceImage.GetByteBufferOffsetXY(boundsRect.Left, boundsRect.Bottom) / 4; // int[] buffer = sourceImage.GetInt32Buffer(); // SetBuffer(buffer, bufferOffset); // return true; // } // return false; //} void SetBuffer(TempMemPtr src, int arrayElemOffset) { int height = this.Height; if ((src.LengthInBytes / 4) < height * Width) { throw new Exception("Your buffer does not have enough room it it for your height and strideInBytes."); } SetBuffer(src); _int32ArrayStartPixelAt = arrayElemOffset; if (this.Stride < 0) //stride in bytes { //TODO: review here int addAmount = -((height - 1) * Width); _int32ArrayStartPixelAt = addAmount + arrayElemOffset; } SetUpLookupTables(); }
public sealed override void GenerateColors(Drawing.Color[] outputColors, int startIndex, int x, int y, int len) { int bytesBetweenPixelsInclusive = srcRW.BytesBetweenPixelsInclusive; ISpanInterpolator spanInterpolator = Interpolator; spanInterpolator.Begin(x + dx, y + dy, len); int x_hr; int y_hr; spanInterpolator.GetCoord(out x_hr, out y_hr); int x_lr = x_hr >> img_subpix_const.SHIFT; int y_lr = y_hr >> img_subpix_const.SHIFT; int bufferIndex; bufferIndex = srcRW.GetByteBufferOffsetXY(x_lr, y_lr); unsafe { TempMemPtr srcBuffPtr = srcRW.GetBufferPtr(); byte * pSource = (byte *)srcBuffPtr.Ptr; { do { //outputColors[startIndex].red = pSource[bufferIndex]; //outputColors[startIndex].green = pSource[bufferIndex]; //outputColors[startIndex].blue = pSource[bufferIndex]; //outputColors[startIndex].alpha = 255; byte grayValue = pSource[bufferIndex]; outputColors[startIndex] = Drawing.Color.FromArgb(255, grayValue, grayValue, grayValue); startIndex++; bufferIndex += bytesBetweenPixelsInclusive; } while (--len != 0); } srcBuffPtr.Release(); } }
public static MemBitmap CopyImgBuffer(this MemBitmap src, int srcX, int srcY, int srcW, int srcH) { //simple copy #if DEBUG Rectangle orgSourceRect = new Rectangle(0, 0, src.Width, src.Height); Rectangle requestRect = new Rectangle(srcX, srcY, srcW, srcH); #endif Rectangle toCopyRect = Rectangle.Intersect( new Rectangle(0, 0, src.Width, src.Height), //orgSourceRect new Rectangle(srcX, srcY, srcW, srcH)); //reqstRect if (toCopyRect.Width == 0 || toCopyRect.Height == 0) { return(null); } //----- MemBitmap copyBmp = new MemBitmap(toCopyRect.Width, toCopyRect.Height); unsafe { using (TempMemPtr srcBufferPtr = MemBitmap.GetBufferPtr(src)) using (TempMemPtr dstBufferPtr = MemBitmap.GetBufferPtr(copyBmp)) { int *srcPtr = (int *)srcBufferPtr.Ptr; int *dstPtr = (int *)dstBufferPtr.Ptr; int lineEnd = srcY + srcH; int orgSrcW = src.Width; for (int line = toCopyRect.Top; line < toCopyRect.Bottom; ++line) { MemMx.memcpy((byte *)dstPtr, (byte *)(srcPtr + ((line * orgSrcW) + toCopyRect.Left)), toCopyRect.Width * 4); dstPtr += toCopyRect.Width; } } } return(copyBmp); }
internal override void BlendPixels(TempMemPtr dstBuffer, int arrayElemOffset, Color[] srcColors, int srcColorOffset, byte[] covers, int coversIndex, bool firstCoverForAll, int count) { if (firstCoverForAll) { int cover = covers[coversIndex]; if (cover == 255) { //version 1 //do //{ // BlendPixel(destBuffer, bufferOffset, sourceColors[sourceColorsOffset++]); // bufferOffset += 4; //} //while (--count != 0); //version 2 //unsafe //{ // fixed (byte* head = &destBuffer[bufferOffset]) // { // int* header2 = (int*)(IntPtr)head; // do // { // Blend32PixelInternal(header2, sourceColors[sourceColorsOffset++]); // header2++;//move next // } // while (--count != 0); // } //} //------------------------------ //version 3: similar to version 2, but have a plan unsafe { //int* dstBuff = (int*)dstBuffer.Ptr; //int* head = &dstBuff[arrayElemOffset]; //fixed (int* head = &dstBuffer[arrayElemOffset]) { int *header2 = (int *)dstBuffer.Ptr + arrayElemOffset; if (count % 2 != 0) { //odd // BlendPixel32Internal(header2, srcColors[srcColorOffset++]); header2++;//move next count--; } //now count is even number while (count > 0) { //now count is even number //--------- //1 BlendPixel32Internal(header2, srcColors[srcColorOffset++]); header2++;//move next count--; //--------- //2 BlendPixel32Internal(header2, srcColors[srcColorOffset++]); header2++;//move next count--; } } } } else { ////version 1 //do //{ // BlendPixel(destBuffer, bufferOffset, sourceColors[sourceColorsOffset].NewFromChangeCoverage(cover)); // bufferOffset += 4; // ++sourceColorsOffset; //} //while (--count != 0); ////version 2 //unsafe //{ // fixed (byte* head = &destBuffer[bufferOffset]) // { // int* header2 = (int*)(IntPtr)head; // do // { // //Blend32PixelInternal(header2, sourceColors[sourceColorsOffset++].NewFromChangeCoverage(cover)); // Blend32PixelInternal(header2, sourceColors[sourceColorsOffset++], cover); // header2++;//move next // } // while (--count != 0); // } //} //------------------------------ //version 3: similar to version 2, but have a plan unsafe { //int* dstBuff = (int*)dstBuffer.Ptr; //int* head = &dstBuff[arrayElemOffset]; //fixed (int* head = &dstBuffer[arrayElemOffset]) { //int* header2 = (int*)(IntPtr)head; int *header2 = (int *)dstBuffer.Ptr + arrayElemOffset; if (count % 2 != 0) { //odd // BlendPixel32Internal(header2, srcColors[srcColorOffset++], cover); header2++;//move next count--; } while (count > 0) { //Blend32PixelInternal(header2, sourceColors[sourceColorsOffset++].NewFromChangeCoverage(cover)); //1. BlendPixel32Internal(header2, srcColors[srcColorOffset++], cover); header2++;//move next count--; //2. BlendPixel32Internal(header2, srcColors[srcColorOffset++], cover); header2++;//move next count--; } } } } } else { unsafe { //int* dstBuff = (int*)dstBuffer.Ptr; //int* dstHead = &dstBuff[arrayElemOffset]; //fixed (int* dstHead = &dstBuffer[arrayElemOffset]) { int *dstBufferPtr = (int *)dstBuffer.Ptr + arrayElemOffset; do { //cover may diff in each loop int cover = covers[coversIndex++]; if (cover == 255) { BlendPixel32Internal(dstBufferPtr, srcColors[srcColorOffset]); } else { BlendPixel32Internal(dstBufferPtr, srcColors[srcColorOffset].NewFromChangeCoverage(cover)); } dstBufferPtr++; ++srcColorOffset; }while (--count != 0); } } } }
unsafe ActualImage GetTransformedBicubicInterpolation() { //4 points sampling //weight between four point PointF ptInPlane = new PointF(); int x1, x2, y1, y2; double dab, dbc, dcd, dda; float dx1, dx2, dy1, dy2, dx1y1, dx1y2, dx2y1, dx2y2; int rectWidth = rect.Width; int rectHeight = rect.Height; var ab_vec = this.AB; var bc_vec = this.BC; var cd_vec = this.CD; var da_vec = this.DA; TempMemPtr bufferPtr = srcCB.GetBufferPtr(); byte * buffer = (byte *)bufferPtr.Ptr; int stride = srcCB.Stride; int bmpWidth = srcCB.Width; int bmpHeight = srcCB.Height; BufferReader4 reader = new BufferReader4(buffer, stride, bmpWidth, bmpHeight); MyColor[] pixelBuffer = new MyColor[16]; byte[] sqPixs = new byte[16]; //Bitmap outputbmp = new Bitmap(rectWidth, rectHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb); ////----------------------------------------------- //var bmpdata2 = outputbmp.LockBits(new Rectangle(0, 0, rectWidth, rectHeight), // System.Drawing.Imaging.ImageLockMode.ReadWrite, outputbmp.PixelFormat); ////----------------------------------------- ActualImage destCB = new ActualImage(rect.Width, rect.Height, PixelFormat.ARGB32); MyImageReaderWriter destWriter = new MyImageReaderWriter(); destWriter.ReloadImage(destCB); //PointF ptInPlane = new PointF(); //int stride2 = bmpdata2.Stride; //byte[] outputBuffer = new byte[stride2 * outputbmp.Height]; // int targetPixelIndex = 0; // int startLine = 0; int rectLeft = this.rect.Left; int rectTop = this.rect.Top; for (int y = 0; y < rectHeight; ++y) { for (int x = 0; x < rectWidth; ++x) { PointF srcPt = new PointF(x, y); srcPt.Offset(rectLeft, rectTop); if (!IsOnPlaneABCD(srcPt)) { continue; } //------------------------------------- dab = Math.Abs(MyVectorHelper.NewFromTwoPoints(vertex[0], srcPt).CrossProduct(ab_vec)); dbc = Math.Abs(MyVectorHelper.NewFromTwoPoints(vertex[1], srcPt).CrossProduct(bc_vec)); dcd = Math.Abs(MyVectorHelper.NewFromTwoPoints(vertex[2], srcPt).CrossProduct(cd_vec)); dda = Math.Abs(MyVectorHelper.NewFromTwoPoints(vertex[3], srcPt).CrossProduct(da_vec)); ptInPlane.X = (float)(srcW * (dda / (dda + dbc))); ptInPlane.Y = (float)(srcH * (dab / (dab + dcd))); x1 = (int)ptInPlane.X; y1 = (int)ptInPlane.Y; if (x1 >= 2 && x1 < srcW - 2 && y1 >= 2 && y1 < srcH - 2) { reader.SetStartPixel(x1, y1); reader.Read16(pixelBuffer); //do interpolate //find src pixel and approximate MyColor color = GetApproximateColor_Bicubic(reader, ptInPlane.X, ptInPlane.Y); //outputBuffer[targetPixelIndex] = (byte)color.b; //outputBuffer[targetPixelIndex + 1] = (byte)color.g; //outputBuffer[targetPixelIndex + 2] = (byte)color.r; //outputBuffer[targetPixelIndex + 3] = (byte)color.a; //targetPixelIndex += 4; destWriter.SetPixel(x, y, new Drawing.Color(color.a, color.b, color.g, color.r)); //TODO:review here blue switch to red channel } } //newline // startLine += stride2; //targetPixelIndex = startLine; } bufferPtr.Release(); //------------------------ //System.Runtime.InteropServices.Marshal.Copy( //outputBuffer, 0, //bmpdata2.Scan0, outputBuffer.Length); //outputbmp.UnlockBits(bmpdata2); ////outputbmp.Save("d:\\WImageTest\\n_lion_bicubic.png"); //return outputbmp; return(destCB); }
///////////////////////////////////////////////////////////////////////////////////// public static void CopyToGdiPlusBitmapSameSize( ActualImage actualImage, SkiaSharp.SKBitmap skBmp) { //agg store image buffer head-down //when copy to window bmp we here to flip //style1: copy row by row *** (fastest)*** { //System.GC.Collect(); //System.Diagnostics.Stopwatch sss = new System.Diagnostics.Stopwatch(); //sss.Start(); //for (int i = 0; i < 1000; ++i) //{ int h = skBmp.Height; int w = skBmp.Width; //BitmapData bitmapData1 = bitmap.LockBits( // new Rectangle(0, 0, // w, // h), // System.Drawing.Imaging.ImageLockMode.ReadWrite, // bitmap.PixelFormat); skBmp.LockPixels(); IntPtr scan0 = skBmp.GetPixels(); int stride = actualImage.Stride; //byte[] srcBuffer = ActualImage.GetBuffer(actualImage); unsafe { TempMemPtr srcBufferPtr = ActualImage.GetBufferPtr(actualImage); //fixed (byte* bufferH = &srcBuffer[0]) byte *bufferH = (byte *)srcBufferPtr.Ptr; { byte *target = (byte *)scan0; int startRowAt = ((h - 1) * stride); for (int y = h; y > 0; --y) { //byte* src = bufferH + ((y - 1) * stride); //System.Runtime.InteropServices.Marshal.Copy( // srcBuffer,//src // startRowAt, // (IntPtr)target, // stride); AggMemMx.memcpy(target, bufferH + startRowAt, stride); startRowAt -= stride; target += stride; } } srcBufferPtr.Release(); } skBmp.UnlockPixels(); //} //sss.Stop(); //long ms = sss.ElapsedMilliseconds; } //----------------------------------- //style2: copy all, then flip again //{ // System.GC.Collect(); // System.Diagnostics.Stopwatch sss = new System.Diagnostics.Stopwatch(); // sss.Start(); // for (int i = 0; i < 1000; ++i) // { // byte[] rawBuffer = ActualImage.GetBuffer(actualImage); // var bmpdata = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), // System.Drawing.Imaging.ImageLockMode.ReadOnly, // bitmap.PixelFormat); // System.Runtime.InteropServices.Marshal.Copy(rawBuffer, 0, // bmpdata.Scan0, rawBuffer.Length); // bitmap.UnlockBits(bmpdata); // bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); // } // sss.Stop(); // long ms = sss.ElapsedMilliseconds; //} //----------------------------------- //----------------------------------- //style3: copy row by row + //{ // System.GC.Collect(); // System.Diagnostics.Stopwatch sss = new System.Diagnostics.Stopwatch(); // sss.Start(); // for (int i = 0; i < 1000; ++i) // { // int h = bitmap.Height; // int w = bitmap.Width; // BitmapData bitmapData1 = bitmap.LockBits( // new Rectangle(0, 0, // w, // h), // System.Drawing.Imaging.ImageLockMode.ReadWrite, // bitmap.PixelFormat); // IntPtr scan0 = bitmapData1.Scan0; // int stride = bitmapData1.Stride; // byte[] buffer = ActualImage.GetBuffer(actualImage); // unsafe // { // fixed (byte* bufferH = &buffer[0]) // { // byte* target = (byte*)scan0; // for (int y = h; y > 0; --y) // { // byte* src = bufferH + ((y - 1) * stride); // for (int n = stride - 1; n >= 0; --n) // { // *target = *src; // target++; // src++; // } // } // } // } // bitmap.UnlockBits(bitmapData1); // } // sss.Stop(); // long ms = sss.ElapsedMilliseconds; //} }
public void SetPixelHighRes(BitmapBlenderBase sourceImage, Color[] destBuffer, int destBufferOffset, int x, int y) { int r, g, b, a; r = g = b = a = LineAA.SUBPIXEL_SCALE * LineAA.SUBPIXEL_SCALE / 2; int weight; int x_lr = x >> LineAA.SUBPIXEL_SHIFT; int y_lr = y >> LineAA.SUBPIXEL_SHIFT; x &= LineAA.SUBPIXEL_MARK; y &= LineAA.SUBPIXEL_MARK; int sourceOffset; // unsafe { TempMemPtr ptr1 = sourceImage.GetBufferPtr(); int * ptr = (int *)ptr1.Ptr; sourceOffset = sourceImage.GetBufferOffsetXY32(x_lr, y_lr); weight = (LineAA.SUBPIXEL_SCALE - x) * (LineAA.SUBPIXEL_SCALE - y); // int ptr_v = ptr[sourceOffset]; r += weight * ((ptr_v >> (CO.R_SHIFT) & 0xff)); // ptr[sourceOffset + CO.R]; g += weight * ((ptr_v >> (CO.G_SHIFT) & 0xff)); //ptr[sourceOffset + CO.G]; b += weight * ((ptr_v >> (CO.B_SHIFT) & 0xff)); //ptr[sourceOffset + CO.B]; a += weight * ((ptr_v >> (CO.A_SHIFT) & 0xff)); //ptr[sourceOffset + CO.A]; // sourceOffset += 1; // sourceImage.BytesBetweenPixelsInclusive; weight = x * (LineAA.SUBPIXEL_SCALE - y); //r += weight * ptr[sourceOffset + CO.R]; //g += weight * ptr[sourceOffset + CO.G]; //b += weight * ptr[sourceOffset + CO.B]; //a += weight * ptr[sourceOffset + CO.A]; ptr_v = ptr[sourceOffset]; r += weight * ((ptr_v >> (CO.R_SHIFT) & 0xff)); // ptr[sourceOffset + CO.R]; g += weight * ((ptr_v >> (CO.G_SHIFT) & 0xff)); //ptr[sourceOffset + CO.G]; b += weight * ((ptr_v >> (CO.B_SHIFT) & 0xff)); //ptr[sourceOffset + CO.B]; a += weight * ((ptr_v >> (CO.A_SHIFT) & 0xff)); //ptr[sourceOffset + CO.A]; // sourceOffset = sourceImage.GetBufferOffsetXY32(x_lr, y_lr + 1); weight = (LineAA.SUBPIXEL_SCALE - x) * y; //r += weight * ptr[sourceOffset + CO.R]; //g += weight * ptr[sourceOffset + CO.G]; //b += weight * ptr[sourceOffset + CO.B]; //a += weight * ptr[sourceOffset + CO.A]; ptr_v = ptr[sourceOffset]; r += weight * ((ptr_v >> (CO.R_SHIFT) & 0xff)); // ptr[sourceOffset + CO.R]; g += weight * ((ptr_v >> (CO.G_SHIFT) & 0xff)); //ptr[sourceOffset + CO.G]; b += weight * ((ptr_v >> (CO.B_SHIFT) & 0xff)); //ptr[sourceOffset + CO.B]; a += weight * ((ptr_v >> (CO.A_SHIFT) & 0xff)); //ptr[sourceOffset + CO.A]; // sourceOffset += 1; // sourceImage.BytesBetweenPixelsInclusive; weight = x * y; //r += weight * ptr[sourceOffset + CO.R]; //g += weight * ptr[sourceOffset + CO.G]; //b += weight * ptr[sourceOffset + CO.B]; //a += weight * ptr[sourceOffset + CO.A]; ptr_v = ptr[sourceOffset]; r += weight * ((ptr_v >> (CO.R_SHIFT) & 0xff)); // ptr[sourceOffset + CO.R]; g += weight * ((ptr_v >> (CO.G_SHIFT) & 0xff)); //ptr[sourceOffset + CO.G]; b += weight * ((ptr_v >> (CO.B_SHIFT) & 0xff)); //ptr[sourceOffset + CO.B]; a += weight * ((ptr_v >> (CO.A_SHIFT) & 0xff)); //ptr[sourceOffset + CO.A]; //destBuffer[destBufferOffset].red = (byte)(r >> LineAA.SUBPIXEL_SHIFT * 2); //destBuffer[destBufferOffset].green = (byte)(g >> LineAA.SUBPIXEL_SHIFT * 2); //destBuffer[destBufferOffset].blue = (byte)(b >> LineAA.SUBPIXEL_SHIFT * 2); //destBuffer[destBufferOffset].alpha = (byte)(a >> LineAA.SUBPIXEL_SHIFT * 2); } destBuffer[destBufferOffset] = Color.FromArgb( (byte)(a >> LineAA.SUBPIXEL_SHIFT * 2), (byte)(r >> LineAA.SUBPIXEL_SHIFT * 2), (byte)(g >> LineAA.SUBPIXEL_SHIFT * 2), (byte)(b >> LineAA.SUBPIXEL_SHIFT * 2) ); }
// Create //-------------------------------------------------------------------- public void Create(IBitmapSrc src) { // we are going to create a dialated image for filtering // we add m_dilation pixels to every side of the image and then copy the image in the x // dirrection into each end so that we can sample into this image to get filtering on x repeating // if the original image look like this // // 123456 // // the new image would look like this // // 0000000000 // 0000000000 // 5612345612 // 0000000000 // 0000000000 _height = (int)AggMath.uceil(src.Height); _width = (int)AggMath.uceil(src.Width); _width_hr = (int)AggMath.uround(src.Width * LineAA.SUBPIXEL_SCALE); _half_height_hr = (int)AggMath.uround(src.Height * LineAA.SUBPIXEL_SCALE / 2); _offset_y_hr = _dilation_hr + _half_height_hr - LineAA.SUBPIXEL_SCALE / 2; _half_height_hr += LineAA.SUBPIXEL_SCALE / 2; int bufferWidth = _width + _dilation * 2; int bufferHeight = _height + _dilation * 2; int bytesPerPixel = src.BitDepth / 8; int newSizeInBytes = bufferWidth * bufferHeight * bytesPerPixel; if (_DataSizeInBytes < newSizeInBytes) { _DataSizeInBytes = newSizeInBytes; _data.Dispose(); IntPtr nativeBuff = System.Runtime.InteropServices.Marshal.AllocHGlobal(_DataSizeInBytes); _data = new TempMemPtr(nativeBuff, _DataSizeInBytes); } _buf = new PixelProcessing.SubBitmapBlender(_data, 0, bufferWidth, bufferHeight, bufferWidth * bytesPerPixel, src.BitDepth, bytesPerPixel); unsafe { using (TempMemPtr destMemPtr = _buf.GetBufferPtr()) using (TempMemPtr srcMemPtr = src.GetBufferPtr()) { int *destBuffer = (int *)destMemPtr.Ptr; int *srcBuffer = (int *)srcMemPtr.Ptr; // copy the image into the middle of the dest for (int y = 0; y < _height; y++) { for (int x = 0; x < _width; x++) { int sourceOffset = src.GetBufferOffsetXY32(x, y); int destOffset = _buf.GetBufferOffsetXY32(_dilation, y + _dilation); destBuffer[destOffset] = srcBuffer[sourceOffset]; } } // copy the first two pixels form the end into the begining and from the begining into the end for (int y = 0; y < _height; y++) { int s1Offset = src.GetBufferOffsetXY32(0, y); int d1Offset = _buf.GetBufferOffsetXY32(_dilation + _width, y); int s2Offset = src.GetBufferOffsetXY32(_width - _dilation, y); int d2Offset = _buf.GetBufferOffsetXY32(0, y); for (int x = 0; x < _dilation; x++) { destBuffer[d1Offset++] = srcBuffer[s1Offset++]; destBuffer[d2Offset++] = srcBuffer[s2Offset++]; } } } } }
public override void DrawImage(Image img, double left, double top) { if (img is ActualImage) { ActualImage actualImage = (ActualImage)img; //create Gdi bitmap from actual image int w = actualImage.Width; int h = actualImage.Height; switch (actualImage.PixelFormat) { case Agg.PixelFormat.ARGB32: { using (SKBitmap newBmp = new SKBitmap(actualImage.Width, actualImage.Height)) { newBmp.LockPixels(); //byte[] actualImgBuffer = ActualImage.GetBuffer(actualImage); TempMemPtr bufferPtr = ActualImage.GetBufferPtr(actualImage); unsafe { byte *actualImgH = (byte *)bufferPtr.Ptr; AggMemMx.memcpy((byte *)newBmp.GetPixels(), actualImgH, actualImage.Stride * actualImage.Height); //System.Runtime.InteropServices.Marshal.Copy( // actualImgBuffer, // 0, // newBmp.GetPixels(), // actualImgBuffer.Length); } bufferPtr.Release(); newBmp.UnlockPixels(); } //newBmp.internalBmp.LockPixels(); //byte[] actualImgBuffer = ActualImage.GetBuffer(actualImage); //System.Runtime.InteropServices.Marshal.Copy( // actualImgBuffer, // 0, // newBmp.internalBmp.GetPixels(), // actualImgBuffer.Length); //newBmp.internalBmp.UnlockPixels(); //return newBmp; //copy data from acutal buffer to internal representation bitmap //using (MySkBmp bmp = MySkBmp.CopyFrom(actualImage)) //{ // _skCanvas.DrawBitmap(bmp.internalBmp, (float)x, (float)y); //} } break; case Agg.PixelFormat.RGB24: { } break; case Agg.PixelFormat.GrayScale8: { } break; default: throw new NotSupportedException(); } } }
public static void CopyFromGdiPlusBitmapSameSizeTo32BitsBuffer( Bitmap windowsBitmap, ActualImage actualImage) { int h = windowsBitmap.Height; int w = windowsBitmap.Width; //byte[] targetBuffer = ActualImage.GetBuffer(actualImage); TempMemPtr targetBufferPtr = ActualImage.GetBufferPtr(actualImage); BitmapData bitmapData1 = windowsBitmap.LockBits( new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); //read as 32 bits IntPtr scan0 = bitmapData1.Scan0; int stride = bitmapData1.Stride; //test //in this version we decided that //Agg's image should use Big-endian bytes. //so we convert the byte order for unsafe { byte *targetH = (byte *)targetBufferPtr.Ptr; int startRowAt = ((h - 1) * stride); byte *src = (byte *)scan0; for (int y = h; y > 0; --y) { //System.Runtime.InteropServices.Marshal.Copy( // (IntPtr)src,//src // targetBuffer, startRowAt, stride); AggMemMx.memcpy(targetH + startRowAt, src, stride); startRowAt -= stride; src += stride; } ////////////////////////////////////////////////////////////////// //fixed (byte* targetH = &targetBuffer[0]) //{ // byte* src = (byte*)scan0; // for (int y = h; y > 0; --y) // { // byte* target = targetH + ((y - 1) * stride); //start at first column of the current row // for (int n = stride - 1; n >= 0;) //n steps // { // //*target = *src; // //target++; // //src++; // //the win gdi+ is // *(target + 2) = *src; //R, 0->2 // *(target + 1) = *(src + 1); //G 1->1 // *(target + 0) = *(src + 2); //B 2->0 // *(target + 3) = *(src + 3); //A 3->3 // //#if !RGBA // // //eg OpenGL, // // /// <summary> // // /// order b // // /// </summary> // // public const int B = 0; // // /// <summary> // // /// order g // // /// </summary> // // public const int G = 1; // // /// <summary> // // /// order b // // /// </summary> // // public const int R = 2; // // /// <summary> // // /// order a // // /// </summary> // // public const int A = 3; // //#else // // //RGBA (Windows GDI+) // // /// <summary> // // /// order b // // /// </summary> // // public const int B = 2; // // /// <summary> // // /// order g // // /// </summary> // // public const int G = 1; // // /// <summary> // // /// order b // // /// </summary> // // public const int R = 0; // // /// <summary> // // /// order a // // /// </summary> // // public const int A = 3; // //#endif // target += 4; // src += 4; // //target++; // //src++; // n -= 4; // } // } //} } targetBufferPtr.Release(); windowsBitmap.UnlockBits(bitmapData1); }
/// <summary> /// copy single pixel /// </summary> /// <param name="dstBuffer"></param> /// <param name="arrayOffset"></param> /// <param name="srcColor"></param> internal abstract void CopyPixel(TempMemPtr dstBuffer, int arrayOffset, Color srcColor);
// /// <summary> /// blend multiple pixels /// </summary> /// <param name="dstBuffer"></param> /// <param name="arrayOffset"></param> /// <param name="srcColor"></param> internal abstract void BlendPixels(TempMemPtr dstBuffer, int arrayOffset, Color srcColor);
/// <summary> /// blend multiple pixels /// </summary> /// <param name="dstBuffer"></param> /// <param name="arrayElemOffset"></param> /// <param name="sourceColors"></param> /// <param name="sourceColorsOffset"></param> /// <param name="covers"></param> /// <param name="coversIndex"></param> /// <param name="firstCoverForAll"></param> /// <param name="count"></param> internal abstract void BlendPixels( TempMemPtr dstBuffer, int arrayElemOffset, Color[] sourceColors, int sourceColorsOffset, byte[] covers, int coversIndex, bool firstCoverForAll, int count);