求推荐好用的图片处理库,需求只是简单的图片创建、拼接。

llllinlink 2019-10-11 11:11:12
RT 需求是把一系列图片依次拼接成一张大图,最终的图片可能会达到2个G以上;
.net原生的Bitmap类创建的位图太占内存了,会导致内存溢出。
有没有现成的图片解码库可以直接操作jpg、png或tif格式的图片呢?
或者哪位大神比较熟悉这些图片格式的数据结构,告诉我怎么通过二进制流来拼接输出,主要是拼接的位置怎么控制没有思路
...全文
135 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
assky124 2019-10-12
  • 打赏
  • 举报
回复
2G的图片啥软件能打开?把图片转成BMP无压缩模式的,然后操作文件处理下。BMP格式简单很多
llllinlink 2019-10-12
  • 打赏
  • 举报
回复
引用 5 楼 X-i-n 的回复:
这是横向拼接的代码供参考,如果横向纵向都需要拼接,对应改一下小图片的相对位置。如果照抄的话,传入的bitmap的格式需要为PixelFormat.Format24bppRgb
        public static Bitmap Merge(Bitmap left, Bitmap right)
        {
            Bitmap bmpOut = new Bitmap(left.Width + right.Width, left.Height);
            unsafe
            {
                BitmapData leftData = left.LockBits(new Rectangle(0, 0, left.Width, left.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                byte* leftPtr = (byte*)(void*)leftData.Scan0;

                BitmapData rightData = right.LockBits(new Rectangle(0, 0, right.Width, left.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                byte* rightPtr = (byte*)(void*)rightData.Scan0;

                BitmapData outData = bmpOut.LockBits(new Rectangle(0, 0, bmpOut.Width, bmpOut.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                byte* outPtr = (byte*)(void*)outData.Scan0;

                int outStride = outData.Stride;
                int offL = leftData.Stride - 3 * left.Width;
                int offR = rightData.Stride - 3 * right.Width;
                for (int y = 0; y < left.Height; ++y)
                {
                    for (int x = 0; x < leftData.Width * 3; ++x)
                    {
                        outPtr[outStride * y + x] = leftPtr[0];
                        ++leftPtr;
                    }
                    leftPtr += offL;

                    for (int x = 0; x < rightData.Width * 3; ++x)
                    {
                        outPtr[outStride * y + 3 * left.Width + x] = rightPtr[0];
                        ++rightPtr;
                    }
                    rightPtr += offR;
                }

                left.UnlockBits(leftData);
                right.UnlockBits(rightData);
                bmpOut.UnlockBits(outData);
                return bmpOut;
            }
        }
        public static Bitmap Merge(Bitmap[] bitmaps)
        {
            int count = bitmaps.Length;
            int height = bitmaps[0].Height;
            int outWidth = bitmaps.Select(b => b.Width).Sum();
            Bitmap bmpOut = new Bitmap(outWidth, bitmaps[0].Height);
            unsafe
            {
                BitmapData[] imgData = new BitmapData[count];
                byte*[] imgPtr = new byte*[count];
                int[] imgOffset = new int[count];
                int[] imgStart = new int[count];
                imgStart[0] = 0;
                for (int i = 0; i < count; i++)
                {
                    imgData[i] = bitmaps[i].LockBits(new Rectangle(0, 0, bitmaps[i].Width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                    imgPtr[i] = (byte*)imgData[i].Scan0;
                    imgOffset[i] = imgData[i].Stride - 3 * bitmaps[i].Width;
                    if (i > 0) imgStart[i] = imgStart[i - 1] + imgData[i - 1].Width * 3;
                }

                BitmapData outData = bmpOut.LockBits(new Rectangle(0, 0, bmpOut.Width, bmpOut.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                byte* outPtr = (byte*)(void*)outData.Scan0;
                int outStride = outData.Stride;

                for (int y = 0; y < height; ++y)
                {
                    for (int idx = 0; idx < count; idx++)
                    {
                        for (int x = 0; x < imgData[idx].Width * 3; ++x)
                        {
                            outPtr[outStride * y + imgStart[idx] + x] = imgPtr[idx][0];
                            ++imgPtr[idx];
                        }
                        imgPtr[idx] += imgOffset[idx];
                    }
                }
                for (int i = 0; i < count; i++)
                {
                    bitmaps[i].UnlockBits(imgData[i]);
                }
                bmpOut.UnlockBits(outData);
                return bmpOut;
            }
        }
不能用bitmap的,第一行就会报错,因为宽高太大导致内存溢出了
llllinlink 2019-10-11
  • 打赏
  • 举报
回复
或者调用画图工具来实现?这样可行嘛?
X-i-n 2019-10-11
  • 打赏
  • 举报
回复
这是横向拼接的代码供参考,如果横向纵向都需要拼接,对应改一下小图片的相对位置。如果照抄的话,传入的bitmap的格式需要为PixelFormat.Format24bppRgb
        public static Bitmap Merge(Bitmap left, Bitmap right)
        {
            Bitmap bmpOut = new Bitmap(left.Width + right.Width, left.Height);
            unsafe
            {
                BitmapData leftData = left.LockBits(new Rectangle(0, 0, left.Width, left.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                byte* leftPtr = (byte*)(void*)leftData.Scan0;

                BitmapData rightData = right.LockBits(new Rectangle(0, 0, right.Width, left.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                byte* rightPtr = (byte*)(void*)rightData.Scan0;

                BitmapData outData = bmpOut.LockBits(new Rectangle(0, 0, bmpOut.Width, bmpOut.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                byte* outPtr = (byte*)(void*)outData.Scan0;

                int outStride = outData.Stride;
                int offL = leftData.Stride - 3 * left.Width;
                int offR = rightData.Stride - 3 * right.Width;
                for (int y = 0; y < left.Height; ++y)
                {
                    for (int x = 0; x < leftData.Width * 3; ++x)
                    {
                        outPtr[outStride * y + x] = leftPtr[0];
                        ++leftPtr;
                    }
                    leftPtr += offL;

                    for (int x = 0; x < rightData.Width * 3; ++x)
                    {
                        outPtr[outStride * y + 3 * left.Width + x] = rightPtr[0];
                        ++rightPtr;
                    }
                    rightPtr += offR;
                }

                left.UnlockBits(leftData);
                right.UnlockBits(rightData);
                bmpOut.UnlockBits(outData);
                return bmpOut;
            }
        }
        public static Bitmap Merge(Bitmap[] bitmaps)
        {
            int count = bitmaps.Length;
            int height = bitmaps[0].Height;
            int outWidth = bitmaps.Select(b => b.Width).Sum();
            Bitmap bmpOut = new Bitmap(outWidth, bitmaps[0].Height);
            unsafe
            {
                BitmapData[] imgData = new BitmapData[count];
                byte*[] imgPtr = new byte*[count];
                int[] imgOffset = new int[count];
                int[] imgStart = new int[count];
                imgStart[0] = 0;
                for (int i = 0; i < count; i++)
                {
                    imgData[i] = bitmaps[i].LockBits(new Rectangle(0, 0, bitmaps[i].Width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                    imgPtr[i] = (byte*)imgData[i].Scan0;
                    imgOffset[i] = imgData[i].Stride - 3 * bitmaps[i].Width;
                    if (i > 0) imgStart[i] = imgStart[i - 1] + imgData[i - 1].Width * 3;
                }

                BitmapData outData = bmpOut.LockBits(new Rectangle(0, 0, bmpOut.Width, bmpOut.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                byte* outPtr = (byte*)(void*)outData.Scan0;
                int outStride = outData.Stride;

                for (int y = 0; y < height; ++y)
                {
                    for (int idx = 0; idx < count; idx++)
                    {
                        for (int x = 0; x < imgData[idx].Width * 3; ++x)
                        {
                            outPtr[outStride * y + imgStart[idx] + x] = imgPtr[idx][0];
                            ++imgPtr[idx];
                        }
                        imgPtr[idx] += imgOffset[idx];
                    }
                }
                for (int i = 0; i < count; i++)
                {
                    bitmaps[i].UnlockBits(imgData[i]);
                }
                bmpOut.UnlockBits(outData);
                return bmpOut;
            }
        }
llllinlink 2019-10-11
  • 打赏
  • 举报
回复
没有嘛。。救救孩子
大鱼> 2019-10-11
  • 打赏
  • 举报
回复
没有效果的,即便你转成BASE64也是一样,图片太大,需要专业的处理。 一般处理大图的时候都是将图片进行分割成多块,你这将多块组成大,还真不了解。
llllinlink 2019-10-11
  • 打赏
  • 举报
回复
画图工具也是创建bitmap,最后压缩输出的

110,546

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧