WPF:图像处理(一)将任意图像转换为16位位图图像

同系列文章:

/* ----------------------------------------------------------
 * 文件名称:FormatConvert.cs
 * 
 * 作者:秦建辉
 * 
 * QQ:36748897
 * 
 * 博客:http://www.firstsolver.com/wordpress/
 * 
 * 开发环境:
 *      Visual Studio V2010
 *      .NET Framework 4 Client Profile
 *      
 * 版本历史:             
 *      V1.0 2012年08月05日
 *           将原始图像转换成格式为Bgr565或者Bgr555的16位图像
------------------------------------------------------------ */
using System;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Splash.WPF.Imaging
{
    public static partial class ImageUtils
    {
        /// <summary>
        /// 将原始图像转换成格式为Bgr565的16位图像
        /// </summary>
        /// <param name="bs">用于转换的原始图像</param>
        /// <returns>转换后格式为Bgr565的16位图像</returns>
        public static BitmapSource ToBgr565(this BitmapSource bs)
        {
            // 将像素格式统一到Bgr32,并提取图像数据
            Int32 PixelHeight = bs.PixelHeight;     // 图像高度
            Int32 PixelWidth = bs.PixelWidth;       // 图像宽度
            Int32 SourceStride = PixelWidth << 2;   // 扫描行跨距
            Byte[] SourcePixels = new Byte[PixelHeight * SourceStride];
            if (bs.Format == PixelFormats.Bgr32 || bs.Format == PixelFormats.Bgra32)
            {   // 拷贝像素数据
                bs.CopyPixels(SourcePixels, SourceStride, 0);
            }
            else
            {   // 先进行像素格式转换,再拷贝像素数据
                new FormatConvertedBitmap(bs, PixelFormats.Bgr32, null, 0).CopyPixels(SourcePixels, SourceStride, 0);
            }

            // Bgr565格式为 RRRRR GGGGGG BBBBB
            Int32 TargetStride = ((PixelWidth + 1) >> 1) << 2;  // 每个像素占2字节,且跨距要求4字节对齐
            Byte[] TargetPixels = new Byte[PixelHeight * TargetStride];            
            for (Int32 i = 0; i < PixelHeight; i++)
            {
                Int32 Index = i * SourceStride;
                Int32 Loc = i * TargetStride;
                for (Int32 j = 0; j < PixelWidth; j++)
                {
                    Byte B = SourcePixels[Index++];
                    Byte G = SourcePixels[Index++];
                    Byte R = SourcePixels[Index++];
                    Index++;    // 跳过A分量

                    TargetPixels[Loc++] = (Byte)(((G << 3) & 0xe0) | ((B >> 3) & 0x1f));
                    TargetPixels[Loc++] = (Byte)((R & 0xf8) | ((G >> 5) & 7));
                }
            }

            return BitmapSource.Create(PixelWidth, PixelHeight, 96, 96, PixelFormats.Bgr565, null, TargetPixels, TargetStride);
        }

        /// <summary>
        /// 将原始图像转换成格式为Bgr555的16位图像
        /// </summary>
        /// <param name="bs">用于转换的原始图像</param>
        /// <returns>转换后格式为Bgr555的16位图像</returns>
        public static BitmapSource ToBgr555(this BitmapSource bs)
        {
            // 将像素格式统一到Bgr32,并提取图像数据
            Int32 PixelHeight = bs.PixelHeight; // 图像高度
            Int32 PixelWidth = bs.PixelWidth;   // 图像宽度
            Int32 SourceStride = PixelWidth << 2;     // 扫描行跨距
            Byte[] SourcePixels = new Byte[PixelHeight * SourceStride];
            if (bs.Format == PixelFormats.Bgr32 || bs.Format == PixelFormats.Bgra32)
            {   // 拷贝像素数据
                bs.CopyPixels(SourcePixels, SourceStride, 0);
            }
            else
            {   // 先进行像素格式转换,再拷贝像素数据
                new FormatConvertedBitmap(bs, PixelFormats.Bgr32, null, 0).CopyPixels(SourcePixels, SourceStride, 0);
            }

            // Bgr555格式为 X RRRRR GGGGG BBBBB
            Int32 TargetStride = ((PixelWidth + 1) >> 1) << 2;  // 每个像素占2字节,且跨距要求4字节对齐
            Byte[] TargetPixels = new Byte[PixelHeight * TargetStride];
            for (Int32 i = 0; i < PixelHeight; i++)
            {
                Int32 Index = i * SourceStride;
                Int32 Loc = i * TargetStride;
                for (Int32 j = 0; j < PixelWidth; j++)
                {
                    Byte B = SourcePixels[Index++];
                    Byte G = SourcePixels[Index++];
                    Byte R = SourcePixels[Index++];
                    Index++;    // 跳过A分量

                    TargetPixels[Loc++] = (Byte)(((G << 2) & 0xe0) | ((B >> 3) & 0x1f));
                    TargetPixels[Loc++] = (Byte)(((R >> 1) & 0x7c) | ((G >> 6) & 3));
                }
            }

            return BitmapSource.Create(PixelWidth, PixelHeight, 96, 96, PixelFormats.Bgr555, null, TargetPixels, TargetStride);
        }
    }
}

演示程序界面:

Comments are closed.