public override void DrawImage(Image img) { MemBitmap memBmp = img as MemBitmap; if (memBmp == null) { //? TODO return; } if (_renderQuality == RenderQuality.Fast) { //todo, review here again TempMemPtr tmp = MemBitmap.GetBufferPtr(memBmp); BitmapBuffer srcBmp = new BitmapBuffer(img.Width, img.Height, tmp.Ptr, tmp.LengthInBytes); //_bxt.BlitRender(srcBmp, false, 1, null); //_bxt.Blit(0, 0, srcBmp.PixelWidth, srcBmp.PixelHeight, srcBmp, 0, 0, srcBmp.PixelWidth, srcBmp.PixelHeight, // ColorInt.FromArgb(255, 255, 255, 255), // BitmapBufferExtensions.BlendMode.Alpha); _bxt.FastAlphaBlit(0, 0, srcBmp, 0, 0, srcBmp.PixelWidth, srcBmp.PixelHeight); return; } //------------------------------- bool useSubPix = UseSubPixelLcdEffect; //save, restore later... //before render an image we turn off vxs subpixel rendering this.UseSubPixelLcdEffect = false; _aggsx.Render(memBmp, null as AffinePlan[]); //restore... this.UseSubPixelLcdEffect = useSubPix; }
public unsafe static TempMemPtr FromBmp(MemBitmap bmp, out byte *headPtr) { TempMemPtr ptr = MemBitmap.GetBufferPtr(bmp); headPtr = (byte *)ptr.Ptr; return(ptr); }
public unsafe static TempMemPtr FromBmp(IBitmapSrc actualBmp, out int *headPtr) { TempMemPtr ptr = actualBmp.GetBufferPtr(); headPtr = (int *)ptr.Ptr; return(ptr); }
public unsafe static TempMemPtr FromBmp(MemBitmap memBmp, out int *headPtr) { TempMemPtr ptr = MemBitmap.GetBufferPtr(memBmp); headPtr = (int *)ptr.Ptr; return(ptr); }
public static int[] CopyImgBuffer(this MemBitmap memBmp, int width, int height, bool flipY = false) { //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; if (flipY) { fixed(int *destHead = &buff2[0]) { byte *destHead2 = (byte *)destHead; srcBuffer += (height - 1) * srcStride; 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; } } } else { 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); }
void DrawBitmap(MemBitmap memBmp, double left, double top, int srcX, int srcY, int srcW, int srcH) { //check image caching system if (_renderQuality == RenderQuality.Fast) { TempMemPtr tmp = MemBitmap.GetBufferPtr(memBmp); unsafe { BitmapBuffer srcBmp = new BitmapBuffer(memBmp.Width, memBmp.Height, tmp.Ptr, tmp.LengthInBytes); try { var src = new BitmapBufferEx.RectD(srcX, srcY, srcW, srcH); var dest = new BitmapBufferEx.RectD(left, top, srcW, srcH); BitmapBuffer bmpBuffer = new BitmapBuffer(memBmp.Width, memBmp.Height, tmp.Ptr, tmp.LengthInBytes); _bxt.CopyBlit(dest, bmpBuffer, src); } catch (Exception ex) { } } return; } //save, restore later... bool useSubPix = UseSubPixelLcdEffect; //before render an image we turn off vxs subpixel rendering this.UseSubPixelLcdEffect = false; if (_orientation == RenderSurfaceOrientation.LeftTop) { //place left upper corner at specific x y _aggsx.Render(memBmp, left, this.Height - (top + memBmp.Height), srcX, srcY, srcW, srcH); } else { //left-bottom as original //place left-lower of the img at specific (x,y) _aggsx.Render(memBmp, left, top, srcX, srcY, srcW, srcH); } //restore... this.UseSubPixelLcdEffect = useSubPix; }
/// <summary> /// copy from mem image direct to hBmpScan0 /// </summary> /// <param name="srcMemBmp"></param> /// <param name="dstHBmpScan0"></param> public static void CopyToWindowsBitmapSameSize( MemBitmap srcMemBmp, IntPtr dstHBmpScan0) { //1st, fast //byte[] rawBuffer = ActualImage.GetBuffer(actualImage); TempMemPtr memPtr = MemBitmap.GetBufferPtr(srcMemBmp); unsafe { MemMx.memcpy((byte *)dstHBmpScan0, (byte *)memPtr.Ptr, srcMemBmp.Stride * srcMemBmp.Height); } //System.Runtime.InteropServices.Marshal.Copy(rawBuffer, 0, // hBmpScan0, rawBuffer.Length); memPtr.Dispose(); }
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); }
///////////////////////////////////////////////////////////////////////////////////// public static void CopyToGdiPlusBitmapSameSizeNotFlip( MemBitmap srcMemBmp, Bitmap dstBitmap) { //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 = dstBitmap.Height; int w = dstBitmap.Width; BitmapData bitmapData1 = dstBitmap.LockBits( new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadWrite, dstBitmap.PixelFormat); IntPtr scan0 = bitmapData1.Scan0; int stride = bitmapData1.Stride; //byte[] srcBuffer = ActualImage.GetBuffer(actualImage); TempMemPtr srcBufferPtr = MemBitmap.GetBufferPtr(srcMemBmp); unsafe { //fixed (byte* bufferH = &srcBuffer[0]) byte *srcBufferH = (byte *)srcBufferPtr.Ptr; { byte *target = (byte *)scan0; int startRowAt = 0; for (int y = 0; y < h; ++y) { //byte* src = bufferH + ((y - 1) * stride); byte *src = srcBufferH + startRowAt; //System.Runtime.InteropServices.Marshal.Copy( // srcBuffer,//src // startRowAt, // (IntPtr)target, // stride); MemMx.memcpy(target, src, stride); startRowAt += stride; target += stride; } } } srcBufferPtr.Dispose(); dstBitmap.UnlockBits(bitmapData1); //} //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 static void CopyFromGdiPlusBitmapSameSizeTo32BitsBuffer( Bitmap srcWindowsBitmap, MemBitmap dstMemBmp) { int h = srcWindowsBitmap.Height; int w = srcWindowsBitmap.Width; TempMemPtr targetBufferPtr = MemBitmap.GetBufferPtr(dstMemBmp); BitmapData bmpData = srcWindowsBitmap.LockBits( new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); //read as 32 bits unsafe { PixelFarm.CpuBlit.NativeMemMx.MemCopy( (byte *)targetBufferPtr.Ptr, (byte *)bmpData.Scan0, bmpData.Stride * dstMemBmp.Height ); } srcWindowsBitmap.UnlockBits(bmpData); //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); // MemMx.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; // // } // // } // //} //} }
public static void Save(MemBitmap bmp, Stream strm) { //------------- unsafe { PixelFarm.CpuBlit.TempMemPtr tmp = MemBitmap.GetBufferPtr(bmp); int *intBuffer = (int *)tmp.Ptr; int imgW = bmp.Width; int imgH = bmp.Height; Hjg.Pngcs.ImageInfo imgInfo = new Hjg.Pngcs.ImageInfo(imgW, imgH, 8, true); //8 bits per channel with alpha Hjg.Pngcs.PngWriter writer = new Hjg.Pngcs.PngWriter(strm, imgInfo); Hjg.Pngcs.ImageLine iline = new Hjg.Pngcs.ImageLine(imgInfo, Hjg.Pngcs.ImageLine.ESampleType.BYTE); bool flipYImg = true; int imgStride = imgW * 4; int srcIndex = 0; int srcIndexRowHead = (tmp.LengthInBytes / 4) - imgW; int startReadAt = 0; if (flipYImg) { srcIndexRowHead = 0; for (int row = 0; row < imgH; row++) { byte[] scanlineBuffer = iline.ScanlineB; srcIndex = srcIndexRowHead; for (int b = 0; b < imgStride;) { int srcInt = intBuffer[srcIndex]; srcIndex++; scanlineBuffer[b] = (byte)((srcInt >> 16) & 0xff); scanlineBuffer[b + 1] = (byte)((srcInt >> 8) & 0xff); scanlineBuffer[b + 2] = (byte)((srcInt) & 0xff); scanlineBuffer[b + 3] = (byte)((srcInt >> 24) & 0xff); b += 4; } srcIndexRowHead += imgW; startReadAt += imgStride; writer.WriteRow(iline, row); } } else { for (int row = 0; row < imgH; row++) { byte[] scanlineBuffer = iline.ScanlineB; srcIndex = srcIndexRowHead; for (int b = 0; b < imgStride;) { int srcInt = intBuffer[srcIndex]; srcIndex++; scanlineBuffer[b] = (byte)((srcInt >> 16) & 0xff); scanlineBuffer[b + 1] = (byte)((srcInt >> 8) & 0xff); scanlineBuffer[b + 2] = (byte)((srcInt) & 0xff); scanlineBuffer[b + 3] = (byte)((srcInt >> 24) & 0xff); b += 4; } srcIndexRowHead -= imgW; startReadAt += imgStride; writer.WriteRow(iline, row); } } writer.End(); } }
/// <summary> /// create thumbnail img with super-sampling technique,(Expensive, High quality thumb) /// </summary> /// <param name="source"></param> /// <param name="dst"></param> public static MemBitmap CreateThumbnailWithSuperSamplingTechnique(this MemBitmap source, float scaleRatio) { // Paint.NET (MIT,from version 3.36.7, see=> https://github.com/rivy/OpenPDN //in this version new image MUST smaller than the original one *** if (scaleRatio >= 1 || scaleRatio < 0) { return(null); } //create new bitmap int newBmpW = (int)Math.Round(source.Width * scaleRatio); int newBmpH = (int)Math.Round(source.Height * scaleRatio); MemBitmap thumbBitmap = new MemBitmap(newBmpW, newBmpH); //*** IBitmapSrc source_1 = (IBitmapSrc)source; unsafe { Rectangle dstRoi2 = new Rectangle(0, 0, newBmpW, newBmpH); int dstWidth = dstRoi2.Width; int dstHeight = dstRoi2.Height; int srcH = source.Height; int srcW = source.Width; TempMemPtr dstMemPtr = MemBitmap.GetBufferPtr(thumbBitmap); int dstStrideInt32 = newBmpW; for (int dstY = dstRoi2.Top; dstY < dstRoi2.Bottom; ++dstY) { //from dst => find proper source (y) //double srcTop = (double)(dstY * srcH) / (double)dstHeight; double srcTop = (double)(dstY * srcH) / (double)dstHeight; double srcTopFloor = Math.Floor(srcTop); double srcTopWeight = 1 - (srcTop - srcTopFloor); int srcTopInt = (int)srcTopFloor; //double srcBottom = (double)((dstY + 1) * srcH) / (double)dstHeight; double srcBottom = (double)((dstY + 1) * srcH) / (double)dstHeight; double srcBottomFloor = Math.Floor(srcBottom - 0.00001); double srcBottomWeight = srcBottom - srcBottomFloor; int srcBottomInt = (int)srcBottomFloor; int *srcBuffer = (int *)(MemBitmap.GetBufferPtr(source)).Ptr; int srcStrideInt32 = source.Width; //*** int *dstAddr = (int *)dstMemPtr.Ptr + (dstStrideInt32 * dstY); //begin at for (int dstX = dstRoi2.Left; dstX < dstRoi2.Right; ++dstX) { //from dst=> find proper source (x) double srcLeft = (double)(dstX * srcW) / (double)dstWidth; double srcLeftFloor = Math.Floor(srcLeft); double srcLeftWeight = 1 - (srcLeft - srcLeftFloor); int srcLeftInt = (int)srcLeftFloor; double srcRight = (double)((dstX + 1) * srcW) / (double)dstWidth; double srcRightFloor = Math.Floor(srcRight - 0.00001); double srcRightWeight = srcRight - srcRightFloor; int srcRightInt = (int)srcRightFloor; double blueSum = 0; double greenSum = 0; double redSum = 0; double alphaSum = 0; //now we know (left,top) of source that we want //then ask the pixel value from source at that pos //(1) left fractional edge { //PaintFx.ColorBgra* srcLeftPtr = source.GetPointAddressUnchecked(srcLeftInt, srcTopInt + 1); int *srcLeftColorAddr = srcBuffer + source_1.GetBufferOffsetXY32(srcLeftInt, srcTopInt + 1); for (int srcY = srcTopInt + 1; srcY < srcBottomInt; ++srcY) { int srcColor = *srcLeftColorAddr; double a_w = ((srcColor >> CO.A_SHIFT) & 0xff) * srcLeftWeight; blueSum += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w; greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w; redSum += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w; alphaSum += a_w; //move to next row srcLeftColorAddr += srcStrideInt32; //srcLeftPtr = (ColorBgra*)((byte*)srcLeftPtr + source._stride); } } // { //(2) right fractional edge //ColorBgra* srcRightPtr = source.GetPointAddressUnchecked(srcRightInt, srcTopInt + 1); int *srcRightColorAddr = srcBuffer + source_1.GetBufferOffsetXY32(srcRightInt, srcTopInt + 1); for (int srcY = srcTopInt + 1; srcY < srcBottomInt; ++srcY) { int srcColor = *srcRightColorAddr; double a_w = ((srcColor >> CO.A_SHIFT) & 0xff) * srcRightWeight; blueSum += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w; greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w; redSum += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w; alphaSum += a_w; //srcRightPtr = (ColorBgra*)((byte*)srcRightPtr + source._stride); srcRightColorAddr += srcStrideInt32; //move to next row } } // { //(3) top fractional edge //ColorBgra* srcTopPtr = source.GetPointAddressUnchecked(srcLeftInt + 1, srcTopInt); int *srcTopColorAddr = srcBuffer + source_1.GetBufferOffsetXY32(srcLeftInt + 1, srcTopInt); for (int srcX = srcLeftInt + 1; srcX < srcRightInt; ++srcX) { int srcColor = *srcTopColorAddr; double a_w = ((srcColor >> CO.A_SHIFT) & 0xff) * srcTopWeight; blueSum += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w; greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w; redSum += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w; alphaSum += a_w; //move to next column //++srcTopPtr; ++srcTopColorAddr; } } // { //(4) bottom fractional edge //ColorBgra* srcBottomPtr = source.GetPointAddressUnchecked(srcLeftInt + 1, srcBottomInt); int *srcBottomColorAddr = srcBuffer + source_1.GetBufferOffsetXY32(srcLeftInt + 1, srcBottomInt); for (int srcX = srcLeftInt + 1; srcX < srcRightInt; ++srcX) { int srcColor = *srcBottomColorAddr; double a_w = ((srcColor >> CO.A_SHIFT) & 0xff) * srcBottomWeight; blueSum += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w; greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w; redSum += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w; alphaSum += a_w; //++srcBottomPtr; //move to next column //++srcTopPtr; ++srcBottomColorAddr; } } { //(5) center area for (int srcY = srcTopInt + 1; srcY < srcBottomInt; ++srcY) { //ColorBgra* srcPtr = source.GetPointAddressUnchecked(srcLeftInt + 1, srcY); int *srcColorAddr = srcBuffer + source_1.GetBufferOffsetXY32(srcLeftInt + 1, srcY); for (int srcX = srcLeftInt + 1; srcX < srcRightInt; ++srcX) { int srcColor = *srcColorAddr; int a = ((srcColor >> CO.A_SHIFT) & 0xff); blueSum += ((srcColor >> CO.B_SHIFT) & 0xff) * a; greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a; redSum += ((srcColor >> CO.R_SHIFT) & 0xff) * a; alphaSum += a; ++srcColorAddr; } } } //(6) four corner pixels { //6.1 //ColorBgra srcTL = source.GetPoint(srcLeftInt, srcTopInt); int srcColor = *(srcBuffer + source_1.GetBufferOffsetXY32(srcLeftInt, srcTopInt)); double a_w = ((srcColor >> CO.A_SHIFT) & 0xff) * (srcTopWeight * srcLeftWeight); blueSum += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w; greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w; redSum += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w; alphaSum += a_w; } { //6.2 //ColorBgra srcTR = source.GetPoint(srcRightInt, srcTopInt); //double srcTRA = srcTR.A; //blueSum += srcTR.B * (srcTopWeight * srcRightWeight) * srcTRA; //greenSum += srcTR.G * (srcTopWeight * srcRightWeight) * srcTRA; //redSum += srcTR.R * (srcTopWeight * srcRightWeight) * srcTRA; //alphaSum += srcTR.A * (srcTopWeight * srcRightWeight); int srcColor = *(srcBuffer + source_1.GetBufferOffsetXY32(srcRightInt, srcTopInt)); double a_w = ((srcColor >> CO.A_SHIFT) & 0xff) * (srcTopWeight * srcRightWeight); blueSum += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w; greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w; redSum += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w; alphaSum += a_w; } { //(6.3) int srcColor = *(srcBuffer + source_1.GetBufferOffsetXY32(srcLeftInt, srcBottomInt)); double a_w = ((srcColor >> CO.A_SHIFT) & 0xff) * (srcBottomWeight * srcLeftWeight); blueSum += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w; greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w; redSum += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w; alphaSum += a_w; //without a //ColorBgra srcBL = source.GetPoint(srcLeftInt, srcBottomInt); //double srcBLA = srcBL.A; //blueSum += srcBL.B * (srcBottomWeight * srcLeftWeight) * srcBLA; //greenSum += srcBL.G * (srcBottomWeight * srcLeftWeight) * srcBLA; //redSum += srcBL.R * (srcBottomWeight * srcLeftWeight) * srcBLA; //alphaSum += srcBL.A * (srcBottomWeight * srcLeftWeight); } { //(6.4) //ColorBgra srcBR = source.GetPoint(srcRightInt, srcBottomInt); //double srcBRA = srcBR.A; //blueSum += srcBR.B * (srcBottomWeight * srcRightWeight) * srcBRA; //greenSum += srcBR.G * (srcBottomWeight * srcRightWeight) * srcBRA; //redSum += srcBR.R * (srcBottomWeight * srcRightWeight) * srcBRA; //alphaSum += srcBR.A * (srcBottomWeight * srcRightWeight); int srcColor = *(srcBuffer + source_1.GetBufferOffsetXY32(srcRightInt, srcBottomInt)); double a_w = ((srcColor >> CO.A_SHIFT) & 0xff) * (srcBottomWeight * srcRightWeight); blueSum += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w; greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w; redSum += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w; alphaSum += a_w; } double area = (srcRight - srcLeft) * (srcBottom - srcTop); double alpha = alphaSum / area; double blue; double green; double red; if (alpha == 0) { blue = 0; green = 0; red = 0; } else { blue = blueSum / alphaSum; green = greenSum / alphaSum; red = redSum / alphaSum; } // add 0.5 so that rounding goes in the direction we want it to blue += 0.5; green += 0.5; red += 0.5; alpha += 0.5; //*** //dstPtr->Bgra = (uint)blue + ((uint)green << 8) + ((uint)red << 16) + ((uint)alpha << 24); //++dstPtr; *dstAddr = ((byte)alpha) << CO.A_SHIFT | ((byte)blue) << CO.B_SHIFT | ((byte)green) << CO.G_SHIFT | ((byte)red) << CO.R_SHIFT; //(uint)blue + ((uint)green << 8) + ((uint)red << 16) + ((uint)alpha << 24); ++dstAddr; } } } return(thumbBitmap); }
//public static void InvertColor(this MemBitmap memBmp) //{ // //temp fix // unsafe // { // Imaging.TempMemPtr tmp = MemBitmap.GetBufferPtr(memBmp); // int* buffer = (int*)tmp.Ptr; // int len32 = tmp.LengthInBytes / 4; // unsafe // { // { // int* head_i32 = (int*)buffer; // for (int n = len32 - 1; n >= 0; --n) // { // int value = *head_i32; // int r = (value >> CO.R_SHIFT) & 0xff; // int g = (value >> CO.G_SHIFT) & 0xff; // int b = (value >> CO.B_SHIFT) & 0xff; // int a = (value >> CO.A_SHIFT) & 0xff; // *head_i32 = ((255 - r) << CO.R_SHIFT) | ((255 - g) << CO.G_SHIFT) | ((255 - b) << CO.B_SHIFT) | ((255 - a) << CO.A_SHIFT); // head_i32++; // } // } // } // } //} internal static void Clear(PixelFarm.CpuBlit.TempMemPtr tmp, Color color) { unsafe { int *buffer = (int *)tmp.Ptr; int len32 = tmp.LengthInBytes / 4; //------------------------------ //fast clear buffer //skip clipping **** //TODO: reimplement clipping*** //------------------------------ if (color == Color.White) { //fast cleat with white color int n = len32; unsafe { //fixed (void* head = &buffer[0]) { uint *head_i32 = (uint *)buffer; for (int i = n - 1; i >= 0; --i) { *head_i32 = 0xffffffff; //white (ARGB) head_i32++; } } } } else if (color == Color.Black) { //fast clear with black color int n = len32; unsafe { //fixed (void* head = &buffer[0]) { uint *head_i32 = (uint *)buffer; for (int i = n - 1; i >= 0; --i) { *head_i32 = 0xff000000; //black (ARGB) head_i32++; } } } } else if (color == Color.Empty) { int n = len32; unsafe { //fixed (void* head = &buffer[0]) { uint *head_i32 = (uint *)buffer; for (int i = n - 1; i >= 0; --i) { *head_i32 = 0x00000000; //empty head_i32++; } } } } else { //other color //#if WIN32 // uint colorARGB = (uint)((color.alpha << 24) | ((color.red << 16) | (color.green << 8) | color.blue)); //#else // uint colorARGB = (uint)((color.alpha << 24) | ((color.blue << 16) | (color.green << 8) | color.red)); //#endif //ARGB uint colorARGB = (uint)((color.A << CO.A_SHIFT) | ((color.R << CO.R_SHIFT) | (color.G << CO.G_SHIFT) | color.B << CO.B_SHIFT)); int n = len32; unsafe { //fixed (void* head = &buffer[0]) { uint *head_i32 = (uint *)buffer; for (int i = n - 1; i >= 0; --i) { *head_i32 = colorARGB; head_i32++; } } } } } }