A class for basic bitmap manipulation: clearing bitmaps, blitting from one bitmap to another etc. Generally methods in this class are quite slow and are only intended for pre-rendering. TODO : replace loops with block copies
Пример #1
0
        public JBitmap CreateCopy()
        {
            JBitmap newBitmap = new JBitmap(w, h, format);

            Blit(newBitmap, w, h);

            return(newBitmap);
        }
Пример #2
0
        public JBitmap CreateCopy()
        {
            JBitmap newBitmap = new JBitmap(w, h, format);
            Blit(newBitmap, w, h);

            return newBitmap;

        }
Пример #3
0
        public void Blit(JBitmap target, int px, int py)
        {
            if (target.format != format)
            {
                throw new Exception("Attempted to blit between bitmaps not of the same format");
            }

            int bpp = (int)format;

            int targetStartX, targetEndX;
            int targetStartY, targetEndY;
            int copyW, copyH;

            targetStartX = Math.Max(px, 0);
            targetEndX   = Math.Min(px + bitmapData.Width, target.bitmapData.Width);

            targetStartY = Math.Max(py, 0);
            targetEndY   = Math.Min(py + bitmapData.Height, target.bitmapData.Height);

            copyW = targetEndX - targetStartX;
            copyH = targetEndY - targetStartY;

            if (copyW < 0)
            {
                return;
            }

            if (copyH < 0)
            {
                return;
            }

            int sourceStartX = targetStartX - px;
            int sourceStartY = targetStartY - py;


            unsafe
            {
                byte *sourcePtr = (byte *)(bitmapData.Scan0);
                byte *targetPtr = (byte *)(target.bitmapData.Scan0);


                byte *targetY = targetPtr + targetStartY * target.bitmapData.Stride;
                byte *sourceY = sourcePtr + sourceStartY * bitmapData.Stride;
                for (int y = 0; y < copyH; y++, targetY += target.bitmapData.Stride, sourceY += bitmapData.Stride)
                {
                    byte *targetOffset = targetY + targetStartX * bpp;
                    byte *sourceOffset = sourceY + sourceStartX * bpp;
                    for (int x = 0; x < copyW * bpp; x++, targetOffset++, sourceOffset++)
                    {
                        *(targetOffset) = *(sourceOffset);
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Blits this bitmap onto the target - clips regions that are out of bounds.
        ///
        /// Only supported for 8bbp
        /// </summary>
        /// <param name="target"></param>
        /// <param name="targetX"></param>
        /// <param name="targetY"></param>
        public void BlitOLD(JBitmap target, int px, int py)
        {
            //currently only supported for 8 bpp source / target
            if (bitmapData.PixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed &&
                target.bitmapData.PixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
            {
                int targetStartX, targetEndX;
                int targetStartY, targetEndY;
                int copyW, copyH;

                targetStartX = Math.Max(px, 0);
                targetEndX   = Math.Min(px + bitmapData.Width, target.bitmapData.Width);

                targetStartY = Math.Max(py, 0);
                targetEndY   = Math.Min(py + bitmapData.Height, target.bitmapData.Height);

                copyW = targetEndX - targetStartX;
                copyH = targetEndY - targetStartY;

                if (copyW < 0)
                {
                    return;
                }

                if (copyH < 0)
                {
                    return;
                }

                int sourceStartX = targetStartX - px;
                int sourceStartY = targetStartY - py;


                unsafe
                {
                    byte *sourcePtr = (byte *)(bitmapData.Scan0);
                    byte *targetPtr = (byte *)(target.bitmapData.Scan0);


                    byte *targetY = targetPtr + targetStartY * target.bitmapData.Stride;
                    byte *sourceY = sourcePtr + sourceStartY * bitmapData.Stride;
                    for (int y = 0; y < copyH; y++, targetY += target.bitmapData.Stride, sourceY += bitmapData.Stride)
                    {
                        byte *targetOffset = targetY + targetStartX;
                        byte *sourceOffset = sourceY + sourceStartX;
                        for (int x = 0; x < copyW; x++, targetOffset++, sourceOffset++)
                        {
                            *(targetOffset) = *(sourceOffset);
                        }
                    }
                }
            }
        }
Пример #5
0
 public void Remove(JBitmap bmpToRemove)
 {
     bitmapList.Remove(bmpToRemove);
     bmpToRemove.Free();
 }
Пример #6
0
 public JBitmap Add(JBitmap bmp)
 {
     bitmapList.Add(bmp);
     return bmp;
 }
Пример #7
0
        /*
       * Resizes this bitmap to a smaller size using area-weighted averaging.
       * 
       */
        public void DownScale(int newWidth, int newHeight)
        {
            JBitmap newBitmap = new JBitmap(newWidth, newHeight, format);

            float xscale = (float)bitmapData.Width / newWidth;
            float yscale = (float)bitmapData.Height / newHeight;


            byte r = 0, g = 0, b = 0, a = 0;
            float summedR = 0f;
            float summedG = 0f;
            float summedB = 0f;
            float summedA = 0f;

            int left, right, top, bottom;  //the area of old pixels covered by the new bitmap


            float targetStartX, targetEndX;
            float targetStartY, targetEndY;

            float leftF, rightF, topF, bottomF; //edges of new pixel in old pixel coords
            float weight;
            float weightScale = xscale * yscale;
            float weightTotalTest = 0f;

            for (int m = 0; m < newHeight; m++)
            {
                for (int n = 0; n < newWidth; n++)
                {

                    leftF = n * xscale;
                    rightF = (n + 1) * xscale;

                    topF = m * yscale;
                    bottomF = (m + 1) * yscale;

                    left = (int)leftF;
                    right = (int)rightF;

                    top = (int)topF;
                    bottom = (int)bottomF;

                    if (left < 0) left = 0;
                    if (top < 0) top = 0;
                    if (right >= bitmapData.Width) right = bitmapData.Width - 1;
                    if (bottom >= bitmapData.Height) bottom = bitmapData.Height - 1;

                    summedR = 0f;
                    summedG = 0f;
                    summedB = 0f;
                    summedA = 0f;
                    weightTotalTest = 0f;

                    for (int j = top; j <= bottom; j++)
                    {
                        for (int i = left; i <= right; i++)
                        {
                            targetStartX = Math.Max(leftF, i);
                            targetEndX = Math.Min(rightF, i + 1);

                            targetStartY = Math.Max(topF, j);
                            targetEndY = Math.Min(bottomF, j + 1);

                            weight = (targetEndX - targetStartX) * (targetEndY - targetStartY);

                            GetPixelFast(i, j, ref r, ref g, ref b, ref a);

                            summedR += weight * r;
                            summedG += weight * g;
                            summedB += weight * b;
                            summedA += weight * a;

                            weightTotalTest += weight;

                        }
                    }

                    summedR /= weightScale;
                    summedG /= weightScale;
                    summedB /= weightScale;
                    summedA /= weightScale;

                    if (summedR < 0) summedR = 0f;
                    if (summedG < 0) summedG = 0f;
                    if (summedB < 0) summedB = 0f;
                    if (summedA < 0) summedA = 0f;

                    if (summedR >= 256) summedR = 255;
                    if (summedG >= 256) summedG = 255;
                    if (summedB >= 256) summedB = 255;
                    if (summedA >= 256) summedA = 255;

                    newBitmap.PutPixelFast(n, m, (byte)summedR, (byte)summedG, (byte)summedB, (byte)summedA);
                }

            }



            this.Free();

            this.bitmap = newBitmap.bitmap;
            this.bitmapData = newBitmap.bitmapData;
            this.format = newBitmap.format;


        }
Пример #8
0
        public void BlitMax(JBitmap target, int px, int py, float strength)
        {

            //currently only supported for 8 bpp source / target
            if (bitmapData.PixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed &&
                target.bitmapData.PixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
            {


                int targetStartX, targetEndX;
                int targetStartY, targetEndY;
                int copyW, copyH;

                targetStartX = Math.Max(px, 0);
                targetEndX = Math.Min(px + bitmapData.Width, target.bitmapData.Width);

                targetStartY = Math.Max(py, 0);
                targetEndY = Math.Min(py + bitmapData.Height, target.bitmapData.Height);

                copyW = targetEndX - targetStartX;
                copyH = targetEndY - targetStartY;

                if (copyW < 0)
                {
                    return;
                }

                if (copyH < 0)
                {
                    return;
                }

                int sourceStartX = targetStartX - px;
                int sourceStartY = targetStartY - py;


                unsafe
                {
                    byte* sourcePtr = (byte*)(bitmapData.Scan0);
                    byte* targetPtr = (byte*)(target.bitmapData.Scan0);
                    int max;

                    byte* targetY = targetPtr + targetStartY * target.bitmapData.Stride;
                    byte* sourceY = sourcePtr + sourceStartY * bitmapData.Stride;
                    for (int y = 0; y < copyH; y++, targetY += target.bitmapData.Stride, sourceY += bitmapData.Stride)
                    {

                        byte* targetOffset = targetY + targetStartX;
                        byte* sourceOffset = sourceY + sourceStartX;
                        for (int x = 0; x < copyW; x++, targetOffset++, sourceOffset++)
                        {
                            max = Math.Max((int)*(targetOffset), (int) (*(sourceOffset) * strength));

                            if (*(sourceOffset) * strength > *(targetOffset))
                            {
                                max = (int) (*(sourceOffset) * strength );

                                if (max > 255)
                                {
                                    *(targetOffset) = 255;
                                }
                                else
                                {
                                    *(targetOffset) = (byte)max;
                                }
                            }




                        }

                    }
                }


            }



        }
Пример #9
0
        public void Blit(JBitmap target, int px, int py)
        {




            if (target.format != format)
            {
                throw new Exception("Attempted to blit between bitmaps not of the same format");
            }

            int bpp = (int)format;

            int targetStartX, targetEndX;
            int targetStartY, targetEndY;
            int copyW, copyH;

            targetStartX = Math.Max(px, 0);
            targetEndX = Math.Min(px + bitmapData.Width, target.bitmapData.Width);

            targetStartY = Math.Max(py, 0);
            targetEndY = Math.Min(py + bitmapData.Height, target.bitmapData.Height);

            copyW = targetEndX - targetStartX;
            copyH = targetEndY - targetStartY;

            if (copyW < 0)
            {
                return;
            }

            if (copyH < 0)
            {
                return;
            }

            int sourceStartX = targetStartX - px;
            int sourceStartY = targetStartY - py;


            unsafe
            {
                byte* sourcePtr = (byte*)(bitmapData.Scan0);
                byte* targetPtr = (byte*)(target.bitmapData.Scan0);


                byte* targetY = targetPtr + targetStartY * target.bitmapData.Stride;
                byte* sourceY = sourcePtr + sourceStartY * bitmapData.Stride;
                for (int y = 0; y < copyH; y++, targetY += target.bitmapData.Stride, sourceY += bitmapData.Stride)
                {

                    byte* targetOffset = targetY + targetStartX*bpp;
                    byte* sourceOffset = sourceY + sourceStartX*bpp;
                    for (int x = 0; x < copyW*bpp; x++, targetOffset++, sourceOffset++)
                    {
                        *(targetOffset) = *(sourceOffset);

                    }

                }
            }



        }
Пример #10
0
 public void Remove(JBitmap bmpToRemove)
 {
     bitmapList.Remove(bmpToRemove);
     bmpToRemove.Free();
 }
Пример #11
0
 public JTexture(JBitmap jbitmap, bool alpha)
 {
     JTextureConstructorHelper(jbitmap.bitmapData, alpha, false);
 }
Пример #12
0
        /*
         * Resizes this bitmap to a smaller size using area-weighted averaging.
         *
         */
        public void DownScale(int newWidth, int newHeight)
        {
            JBitmap newBitmap = new JBitmap(newWidth, newHeight, format);

            float xscale = (float)bitmapData.Width / newWidth;
            float yscale = (float)bitmapData.Height / newHeight;


            byte  r = 0, g = 0, b = 0, a = 0;
            float summedR = 0f;
            float summedG = 0f;
            float summedB = 0f;
            float summedA = 0f;

            int left, right, top, bottom;  //the area of old pixels covered by the new bitmap


            float targetStartX, targetEndX;
            float targetStartY, targetEndY;

            float leftF, rightF, topF, bottomF; //edges of new pixel in old pixel coords
            float weight;
            float weightScale     = xscale * yscale;
            float weightTotalTest = 0f;

            for (int m = 0; m < newHeight; m++)
            {
                for (int n = 0; n < newWidth; n++)
                {
                    leftF  = n * xscale;
                    rightF = (n + 1) * xscale;

                    topF    = m * yscale;
                    bottomF = (m + 1) * yscale;

                    left  = (int)leftF;
                    right = (int)rightF;

                    top    = (int)topF;
                    bottom = (int)bottomF;

                    if (left < 0)
                    {
                        left = 0;
                    }
                    if (top < 0)
                    {
                        top = 0;
                    }
                    if (right >= bitmapData.Width)
                    {
                        right = bitmapData.Width - 1;
                    }
                    if (bottom >= bitmapData.Height)
                    {
                        bottom = bitmapData.Height - 1;
                    }

                    summedR         = 0f;
                    summedG         = 0f;
                    summedB         = 0f;
                    summedA         = 0f;
                    weightTotalTest = 0f;

                    for (int j = top; j <= bottom; j++)
                    {
                        for (int i = left; i <= right; i++)
                        {
                            targetStartX = Math.Max(leftF, i);
                            targetEndX   = Math.Min(rightF, i + 1);

                            targetStartY = Math.Max(topF, j);
                            targetEndY   = Math.Min(bottomF, j + 1);

                            weight = (targetEndX - targetStartX) * (targetEndY - targetStartY);

                            GetPixelFast(i, j, ref r, ref g, ref b, ref a);

                            summedR += weight * r;
                            summedG += weight * g;
                            summedB += weight * b;
                            summedA += weight * a;

                            weightTotalTest += weight;
                        }
                    }

                    summedR /= weightScale;
                    summedG /= weightScale;
                    summedB /= weightScale;
                    summedA /= weightScale;

                    if (summedR < 0)
                    {
                        summedR = 0f;
                    }
                    if (summedG < 0)
                    {
                        summedG = 0f;
                    }
                    if (summedB < 0)
                    {
                        summedB = 0f;
                    }
                    if (summedA < 0)
                    {
                        summedA = 0f;
                    }

                    if (summedR >= 256)
                    {
                        summedR = 255;
                    }
                    if (summedG >= 256)
                    {
                        summedG = 255;
                    }
                    if (summedB >= 256)
                    {
                        summedB = 255;
                    }
                    if (summedA >= 256)
                    {
                        summedA = 255;
                    }

                    newBitmap.PutPixelFast(n, m, (byte)summedR, (byte)summedG, (byte)summedB, (byte)summedA);
                }
            }



            this.Free();

            this.bitmap     = newBitmap.bitmap;
            this.bitmapData = newBitmap.bitmapData;
            this.format     = newBitmap.format;
        }
Пример #13
0
        /// <summary>
        /// Additively blits onto the target.
        ///
        /// Supports just 24bpp (source and target)
        /// </summary>
        /// <param name="target"></param>
        /// <param name="targetX"></param>
        /// <param name="targetY"></param>
        public void BlitAdditive24(JBitmap target, int px, int py, float strength)
        {
            //currently only supported for 8 bpp source / target
            if (bitmapData.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb &&
                target.bitmapData.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb)
            {
                int targetStartX, targetEndX;
                int targetStartY, targetEndY;
                int copyW, copyH;

                targetStartX = Math.Max(px, 0);
                targetEndX   = Math.Min(px + bitmapData.Width, target.bitmapData.Width);

                targetStartY = Math.Max(py, 0);
                targetEndY   = Math.Min(py + bitmapData.Height, target.bitmapData.Height);

                copyW = targetEndX - targetStartX;
                copyH = targetEndY - targetStartY;

                if (copyW < 0)
                {
                    return;
                }

                if (copyH < 0)
                {
                    return;
                }

                int sourceStartX = targetStartX - px;
                int sourceStartY = targetStartY - py;


                unsafe
                {
                    byte *sourcePtr = (byte *)(bitmapData.Scan0);
                    byte *targetPtr = (byte *)(target.bitmapData.Scan0);
                    int   sum;

                    byte *targetY = targetPtr + targetStartY * target.bitmapData.Stride;
                    byte *sourceY = sourcePtr + sourceStartY * bitmapData.Stride;
                    for (int y = 0; y < copyH; y++, targetY += target.bitmapData.Stride, sourceY += bitmapData.Stride)
                    {
                        byte *targetOffset = targetY + targetStartX * 3;
                        byte *sourceOffset = sourceY + sourceStartX * 3;
                        for (int x = 0; x < copyW * 3; x++, targetOffset++, sourceOffset++)
                        {
                            sum = (int)*(targetOffset) + (int)(*(sourceOffset) * strength);

                            if (sum > 255)
                            {
                                *(targetOffset) = 255;
                            }
                            else
                            {
                                *(targetOffset) = (byte)sum;
                            }
                        }
                    }
                }
            }
        }
Пример #14
0
 public JTexture(JBitmap jbitmap, bool alpha, bool padToPowerOfTwo)
 {
     JTextureConstructorHelper(jbitmap.bitmapData, alpha, padToPowerOfTwo);
 }
Пример #15
0
 public JTexture(JBitmap jbitmap, bool alpha)
 {
     JTextureConstructorHelper(jbitmap.bitmapData, alpha, false);
 }
Пример #16
0
 public JTexture(JBitmap jbitmap, bool alpha, bool padToPowerOfTwo)
 {
     JTextureConstructorHelper(jbitmap.bitmapData, alpha, padToPowerOfTwo);
 }
Пример #17
0
 public JBitmap Add(JBitmap bmp)
 {
     bitmapList.Add(bmp);
     return(bmp);
 }