看了不少图片旋转的帖子,旋转是可以的, 但是都是原始的图片旋转。但是我的情况是:图片放置在一个长方形的外框里面,外框的长宽是固定的,图片只能在框里面旋转。如果按照原始图像旋转的话,就会出现图像被截断没法显示的情况(初始的时候图像的长度等于外框的长宽,比如当图像转了90度,刚好垂直于外框的时候,图像明显长于外框的宽度,就显示不全了)。请问,在旋转的时候,怎么根据旋转的角度,计算当前图片的长宽呢?实时的改变图片的大小。(其实就是计算在当前旋转角度下,落在外框中最大的图片矩形,并保持原有的长宽比例)。请大家给于指点。谢谢

解决方案 »

  1.   

    外框的长宽是固定的,看你自成一体么转,转90度就是把图片高度变为宽度,这是你羊断是高度大于PIC的高度,还是宽度大于PIC的宽度,以大的为基准,按比例缩放。
      

  2.   

    假如你的PIC是100X80(固定),缩放比是0.8,图片是100X80,你image转90度后图片已变为80X100,原来的高是80,现在是100,你的图片宽应是80*0.8,高度是80
      

  3.   

    参考这个,记得是参考,不是照搬,因为它添加了一个图片外框:http://blog.csdn.net/ki1381/article/details/1495943这里得出的新图,尺寸上会因为旋转而变化,但是没关系,然后调用一个方法按比例缩放即可。
            public static Bitmap GenThumbnail(Bitmap imageFrom, int width, int height)
            {
                // 源图宽度及高度 
                int imageFromWidth = imageFrom.Width;
                int imageFromHeight = imageFrom.Height;
                
                // 生成的缩略图实际宽度及高度 
                if (width >= imageFromWidth && height >= imageFromHeight)
                {
                    return imageFrom;
                }
                else
                {
                    // 生成的缩略图在上述"画布"上的位置 
                    int X = 0;
                    int Y = 0;                decimal wpercent = (decimal)width / imageFromWidth;
                    decimal hpercent = (decimal)height / imageFromHeight;
                    if (wpercent > hpercent)
                    {
                        width = (int)(imageFromWidth * hpercent);
                    }
                    else if (wpercent < hpercent)
                    {
                        height = (int)(imageFromHeight * wpercent);
                    }                // 创建画布 
                    using (Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb))
                    {
                        bmp.SetResolution(imageFrom.HorizontalResolution, imageFrom.VerticalResolution);
                        using (Graphics g = Graphics.FromImage(bmp))
                        {                        // 用白色清空 
                            g.Clear(Color.White);                        // 指定高质量的双三次插值法。执行预筛选以确保高质量的收缩。此模式可产生质量最高的转换图像。 
                            g.InterpolationMode = InterpolationMode.HighQualityBicubic;                        // 指定高质量、低速度呈现。 
                            g.SmoothingMode = SmoothingMode.HighQuality;                        // 在指定位置并且按指定大小绘制指定的 Image 的指定部分。 
                            g.DrawImage(imageFrom, new Rectangle(X, Y, width, height), new Rectangle(0, 0, imageFromWidth, imageFromHeight), GraphicsUnit.Pixel);                        return bmp;
                        }
                    }
                }
            }
      

  4.   

    你好,请问你使用过GenThumbnail这个方法没?我写了个测试demo,新建了个bitmap,然后调用GenThumbnail,不能返回正确的bitmap,会报参数异常。还有,这里的width和height是代表什么呢,缩放后的宽高吗?针对我的问题,我是没法通过旋转的角度得到任意时刻图片的高宽,这是问题所在。
      

  5.   

      Private Sub NumericUpDown1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NumericUpDown1.ValueChanged
            Dim OldImgSize As Size = _Bitmap1.Size
            Try
                If _LargeEmptyBP IsNot Nothing Then _LargeEmptyBP.Dispose()
                _LargeEmptyBP = New Bitmap(1000, 1000) '定义足够大的绘制区域,以便容纳旋转后的图像
                Dim Rct As RectangleF
                Using G As Graphics = Graphics.FromImage(_LargeEmptyBP)
                    Dim Gs As Drawing2D.GraphicsState = Nothing
                    Gs = G.Save
                    G.TranslateTransform(500, 500)
                    G.RotateTransform(NumericUpDown1.Value) '旋转的角度
                    G.DrawImage(_Bitmap1, New Rectangle(-OldImgSize.Width / 2, -OldImgSize.Height / 2, OldImgSize.Width, OldImgSize.Height), New Rectangle(0, 0, OldImgSize.Width, OldImgSize.Height), GraphicsUnit.Pixel)
                    G.Restore(Gs)
                End Using
                Rct = GetMinRect(_LargeEmptyBP) '获取经过裁切后的最小矩形图形范围
                Dim WW, HH As Integer
                WW = Rct.Width : HH = Rct.Height
                If B1 IsNot Nothing Then B1.Dispose()
                B1 = New Bitmap(WW, HH)
                Using G As Graphics = Graphics.FromImage(B1)
                    G.DrawImage(_LargeEmptyBP, New Rectangle(0, 0, Rct.Width, Rct.Height), Rct, GraphicsUnit.Pixel)
                End Using
                If B2 IsNot Nothing Then B2.Dispose()
                B2 = New Bitmap(PicBx.Width, PicBx.Height)
                Using G As Graphics = Graphics.FromImage(B2)
                    G.Clear(Color.White)
                    Dim CompWith As Double = 0
                    Dim DrawX, DrawY As Integer
                    '计算适当缩放比例
                    If PicBx.Width <= Rct.Width Then CompWith = PicBx.Width / Rct.Width
                    If PicBx.Height <= Rct.Height Then CompWith = PicBx.Height / Rct.Height
                    CompWith = IIf(CompWith = 0, 1, CompWith)
                    DrawX = (PicBx.Width - Rct.Width * CompWith) / 2
                    DrawY = (PicBx.Height - Rct.Height * CompWith) / 2
                    G.DrawImage(B1, New Rectangle(DrawX, DrawY, Rct.Width * CompWith, Rct.Height * CompWith), New Rectangle(0, 0, Rct.Width, Rct.Height), GraphicsUnit.Pixel)
                End Using
                PicBx.BackgroundImage = B2
            Catch ex As Exception
                Console.WriteLine(ex.Message)
            End Try
        End Sub    ''' <summary>
        ''' 获取经裁剪后的最小容纳图形区域
        ''' </summary>
        ''' <param name="B"></param>
        ''' <returns></returns>
        ''' <res></res>
        Private Function GetMinRect(ByVal B As Bitmap) As Rectangle
            Dim XX, YY, WW, HH, _W, _H As Integer
            Dim bmpDATA As New BitmapData
            bmpDATA = B.LockBits(New Rectangle(0, 0, B.Width - 1, B.Height - 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb)
            _W = bmpDATA.Stride : _H = bmpDATA.Height
            Dim BTS(bmpDATA.Stride * bmpDATA.Height) As Byte
            Runtime.InteropServices.Marshal.Copy(bmpDATA.Scan0, BTS, 0, BTS.Length - 1)
            B.UnlockBits(bmpDATA)
            Dim t1, t2, t3, t4 As Integer
            t1 = BTS(0) : t2 = BTS(1) : t3 = BTS(2) : t4 = BTS(3)
            Dim LastIndex As Integer = 0
            XX = -1 : YY = -1
            For I As Integer = 0 To _H - 1
                For J As Integer = 0 To _W - 4 Step 4
                    LastIndex = I * _W + J
                    If BTS(LastIndex) <> t1 OrElse BTS(LastIndex + 1) <> t2 OrElse BTS(LastIndex + 2) <> t3 OrElse BTS(LastIndex + 3) <> t4 Then
                        If YY = -1 Then YY = I
                        If XX = -1 Then
                            XX = J
                        Else
                            XX = Math.Min(XX, J)
                        End If
                    End If
                Next
            Next
            WW = -1 : HH = -1
            For I As Integer = _H - 1 To 0 Step -1
                For J As Integer = _W - 4 To 0 Step -4
                    LastIndex = I * _W + J
                    If BTS(LastIndex) <> t1 OrElse BTS(LastIndex + 1) <> t2 OrElse BTS(LastIndex + 2) <> t3 OrElse BTS(LastIndex + 3) <> t4 Then
                        If HH = -1 Then HH = I
                        If WW = -1 Then
                            WW = J
                        Else
                            WW = Math.Max(WW, J)
                        End If
                    End If
                Next
            Next
            Return New Rectangle(XX / 4, YY, (WW - XX) / 4, HH - YY)
        End Function
      

  6.   

    这个其实不算什么算法了,不过至少不参与到角度计算,没那么复杂。由于昨晚连续发了3次,没法把申明也放上去,现在补上:Imports System.Drawing.Imaging    Private _LargeEmptyBP, B1, B2 As Bitmap
        Private _Bitmap1 As New Bitmap("C:\Users\Administrator\Desktop\新建文件夹\bullet bil.png")
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load   VB不懂的可以在线转换成C#代码。
      

  7.   

    GenThumbnail是我稍加修改的,忘记修改返回值类型的同时,修改using部分了,原先不是返回Bitmap,而是返回MemoryStream,所以你看内部代码,有using关闭创建的img对象,如果要返回这个img对象,则必须去掉using,不然这个对象都销毁了,自然无法用来返回。
      

  8.   

    兄弟一看就是GDI+,为啥不用这个图做头像啊。
      

  9.   

        对啊,之前我一直用角度去计算,要考虑不同的旋转区域的计算问题,有点复杂,这样简单了很多。
        如果可以的话,那麻烦你转个c#代码, 这个问题拖得比较久了,我从来没有用过vb,要转化成c#的话,要花不少时间。再次感谢
      

  10.   


    也可以不这么做(画图后再用像素找端点,一个是速度慢了,一个是有边角颜色的局限,不能是画布颜色)。
    C# Drawing2D库已经提供了Matrix类,可以简单的来判断旋转的新顶点:
    Matrix matrix = new Matrix(); 
    matrix.Rotate(angle);
    matrix.TransformPoints(corners);
    用新顶点就可以算出需要缩放的比例了。
    public partial class Form1 : Form
    {
        Bitmap bmp = new Bitmap("c:\\temp\\penguins.jpg");
        Rectangle boundingBox = new Rectangle(50, 50, 200, 150);
        PointF center = new PointF(150, 125);
        float angle, lastAngle, baseAngle, scale = 1.0f;    public Form1()
        {
            InitializeComponent();
            this.DoubleBuffered = true;
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            lastAngle = angle;
            baseAngle = (float)(Math.Atan2(e.Y - center.Y, e.X - center.X) * 180 / Math.PI) + 90;
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (this.Capture == false) return;        float currentAngle = (float)(Math.Atan2(e.Y - center.Y, e.X - center.X) * 180 / Math.PI) + 90;
            angle = lastAngle + (currentAngle - baseAngle);        float halfWidth = boundingBox.Width / 2.0f, halfHeight = boundingBox.Height / 2.0f;
            PointF[] corners = { new PointF(-halfWidth, halfHeight), new PointF(halfWidth, halfHeight) };
            Matrix matrix = new Matrix(); matrix.Rotate(angle);
            matrix.TransformPoints(corners);        float bleedX = Math.Max(Math.Abs(corners[0].X), Math.Abs(corners[1].X));
            float bleedY = Math.Max(Math.Abs(corners[0].Y), Math.Abs(corners[1].Y));
            scale = Math.Min(halfWidth / bleedX, halfHeight / bleedY);        this.Invalidate();
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.DrawRectangle(Pens.Red, boundingBox.X-1, boundingBox.Y-1, boundingBox.Width+1, boundingBox.Height + 1);
            e.Graphics.TranslateTransform(center.X, center.Y);
            e.Graphics.RotateTransform(angle);
            e.Graphics.ScaleTransform(scale, scale);
            e.Graphics.TranslateTransform(-center.X, -center.Y);
            e.Graphics.DrawImage(bmp, boundingBox);
        }
    }
      

  11.   

    using Microsoft.VisualBasic;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Diagnostics;
    using System.Drawing.Imaging;
    public class Form1
    {
    private Bitmap _LargeEmptyBP;
    private Bitmap B1;
    private Bitmap B2;
    private Bitmap _Bitmap1 = new Bitmap("C:\\Users\\Administrator\\Desktop\\新建文件夹\\bullet bil.png"); private void Form1_Load(System.Object sender, System.EventArgs e)
    {
    } private void NumericUpDown1_ValueChanged(System.Object sender, System.EventArgs e)
    {
    Size OldImgSize = _Bitmap1.Size;
    try {
    if (_LargeEmptyBP != null)
    _LargeEmptyBP.Dispose();
    _LargeEmptyBP = new Bitmap(1000, 1000);
    //定义足够大的绘制区域,以便容纳旋转后的图像
    RectangleF Rct = default(RectangleF);
    using (Graphics G = Graphics.FromImage(_LargeEmptyBP)) {
    Drawing2D.GraphicsState Gs = null;
    Gs = G.Save;
    G.TranslateTransform(500, 500);
    G.RotateTransform(NumericUpDown1.Value);
    //旋转的角度
    G.DrawImage(_Bitmap1, new Rectangle(-OldImgSize.Width / 2, -OldImgSize.Height / 2, OldImgSize.Width, OldImgSize.Height), new Rectangle(0, 0, OldImgSize.Width, OldImgSize.Height), GraphicsUnit.Pixel);
    G.Restore(Gs);
    }
    Rct = GetMinRect(_LargeEmptyBP);
    //获取经过裁切后的最小矩形图形范围
    int WW = 0;
    int HH = 0;
    WW = Rct.Width;
    HH = Rct.Height;
    if (B1 != null)
    B1.Dispose();
    B1 = new Bitmap(WW, HH);
    using (Graphics G = Graphics.FromImage(B1)) {
    G.DrawImage(_LargeEmptyBP, new Rectangle(0, 0, Rct.Width, Rct.Height), Rct, GraphicsUnit.Pixel);
    }
    if (B2 != null)
    B2.Dispose();
    B2 = new Bitmap(PicBx.Width, PicBx.Height);
    using (Graphics G = Graphics.FromImage(B2)) {
    G.Clear(Color.White);
    double CompWith = 0;
    int DrawX = 0;
    int DrawY = 0;
    //计算适当缩放比例
    if (PicBx.Width <= Rct.Width)
    CompWith = PicBx.Width / Rct.Width;
    if (PicBx.Height <= Rct.Height)
    CompWith = PicBx.Height / Rct.Height;
    CompWith = (CompWith == 0 ? 1 : CompWith);
    DrawX = (PicBx.Width - Rct.Width * CompWith) / 2;
    DrawY = (PicBx.Height - Rct.Height * CompWith) / 2;
    G.DrawImage(B1, new Rectangle(DrawX, DrawY, Rct.Width * CompWith, Rct.Height * CompWith), new Rectangle(0, 0, Rct.Width, Rct.Height), GraphicsUnit.Pixel);
    }
    PicBx.BackgroundImage = B2;
    } catch (Exception ex) {
    Console.WriteLine(ex.Message);
    }
    } /// <summary>
    /// 获取经裁剪后的最小容纳图形区域
    /// </summary>
    /// <param name="B"></param>
    /// <returns></returns>
    /// <res></res>
    private Rectangle GetMinRect(Bitmap B)
    {
    int XX = 0;
    int YY = 0;
    int WW = 0;
    int HH = 0;
    int _W = 0;
    int _H = 0;
    BitmapData bmpDATA = new BitmapData();
    bmpDATA = B.LockBits(new Rectangle(0, 0, B.Width - 1, B.Height - 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    _W = bmpDATA.Stride;
    _H = bmpDATA.Height;
    byte[] BTS = new byte[bmpDATA.Stride * bmpDATA.Height + 1];
    System.Runtime.InteropServices.Marshal.Copy(bmpDATA.Scan0, BTS, 0, BTS.Length - 1);
    B.UnlockBits(bmpDATA);
    int t1 = 0;
    int t2 = 0;
    int t3 = 0;
    int t4 = 0;
    t1 = BTS[0];
    t2 = BTS[1];
    t3 = BTS[2];
    t4 = BTS[3];
    int LastIndex = 0;
    XX = -1;
    YY = -1;
    for (int I = 0; I <= _H - 1; I++) {
    for (int J = 0; J <= _W - 4; J += 4) {
    LastIndex = I * _W + J;
    if (BTS[LastIndex] != t1 || BTS[LastIndex + 1] != t2 || BTS[LastIndex + 2] != t3 || BTS[LastIndex + 3] != t4) {
    if (YY == -1)
    YY = I;
    if (XX == -1) {
    XX = J;
    } else {
    XX = Math.Min(XX, J);
    }
    }
    }
    }
    WW = -1;
    HH = -1;
    for (int I = _H - 1; I >= 0; I += -1) {
    for (int J = _W - 4; J >= 0; J += -4) {
    LastIndex = I * _W + J;
    if (BTS[LastIndex] != t1 || BTS[LastIndex + 1] != t2 || BTS[LastIndex + 2] != t3 || BTS[LastIndex + 3] != t4) {
    if (HH == -1)
    HH = I;
    if (WW == -1) {
    WW = J;
    } else {
    WW = Math.Max(WW, J);
    }
    }
    }
    }
    return new Rectangle(XX / 4, YY, (WW - XX) / 4, HH - YY);
    } private void Form1_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
    {
    Bitmap B = new Bitmap(this.Width, this.Height);
    int J = 0;
    for (int I = 0; I <= 360; I += 5) {
    this.NumericUpDown1.Value = I;
    if (B != null)
    B.Dispose();
    B = new Bitmap(this.Width, this.Height);
    this.DrawToBitmap(B, new Rectangle(0, 0, this.Width, this.Height));
    J += 1;
    B.Save("C:\\Users\\Administrator\\Desktop\\新建文件夹\\A\\" + "A" + J + ".jpg", ImageFormat.Jpeg);
    }
    }
    public Form1()
    {
    MouseDoubleClick += Form1_MouseDoubleClick;
    Load += Form1_Load;
    }
    }
      

  12.   

    君妞不给分我,junjun1984给分我!
      

  13.   

    两种方法能实现:
    1、图片上套一个框,让框转这样保证图片不失真,(如果是WEB程序可以用脚本实现)。
    2、转动的时候动态运算,做压缩和放大处理,这样多少会有失真情况。
    动态压缩放大代码:
    /// <summary>
    /// 高质量缩略图
    /// </summary>
    /// <param name="maxWidth"></param>
    /// <param name="maxHeight"></param>
    /// <param name="width"></param>
    /// <param name="height"></param>
    /// <returns></returns>
    private static Size NewSize( int maxWidth,int maxHeight, int width,int height )  
    {
    double w = 0.0;
    double h = 0.0;
    double sw = Convert.ToDouble(width);
    double sh = Convert.ToDouble(height);
    double mw = Convert.ToDouble(maxWidth);
    double mh = Convert.ToDouble(maxHeight);
    if (sw < mw && sh < mh)
    {
    w = sw;
    h = sh;
    }
    else if ((sw/sh) > (mw/mh))
    {
    w = maxWidth;
    h = (w * sh)/sw;
    }
    else
    {
    h = maxHeight;
    w = (h * sw)/sh;
    }
    return new Size( Convert.ToInt32(w),Convert.ToInt32(h));
    } private static void Madefile(Bitmap info)
    {
    int tw =500;
    int th =400;
    string fname ="kkkkkk.jpg";
    if(true)
    {
    System.Drawing.Image img = (System.Drawing.Image)info;
    System.Drawing.Imaging.ImageFormat thisFormat = img.RawFormat;
    Size newSize = NewSize( tw, th, img.Width, img.Height );
    Bitmap outBmp = new Bitmap( newSize.Width, newSize.Height );
    Graphics g = Graphics.FromImage( outBmp );
    // 设置画布的描绘质量
    g.CompositingQuality = CompositingQuality.HighQuality;
    g.SmoothingMode = SmoothingMode.HighQuality;
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g.DrawImage( img, new Rectangle( 0, 0, newSize.Width, newSize.Height ),0, 0, img.Width, img.Height, GraphicsUnit.Pixel );
    g.Dispose( );
    // 以下代码为保存图片时,设置压缩质量
    EncoderParameters encoderParams = new EncoderParameters( );
    long[] quality = new long[1];
    quality[0] = 100;
    EncoderParameter encoderParam = new EncoderParameter( System.Drawing.Imaging.Encoder.Quality, quality );
    encoderParams.Param[0] = encoderParam;
    //获得包含有关内置图像编码解码器的信息的ImageCodecInfo 对象.
    ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders( );
    ImageCodecInfo jpegICI = null;
    for ( int x = 0;x < arrayICI.Length;x++ )
    {
    if ( arrayICI[x].FormatDescription.Equals( "JPEG" ) )
    {
    jpegICI = arrayICI[x];
    //设置JPEG编码
    break;
    }
    }
    if ( jpegICI != null )
    {
    outBmp.Save( "C:/"+fname, jpegICI, encoderParams );
    }
    img.Dispose( );
    outBmp.Dispose( );
    }
    }
      

  14.   

    假设以图像的中心为旋转的圆心,先计算出任意一个角点的旋转后的坐标A,与原坐标相比B,就可以得出旋转所需的空间。在声明一个新空间时,可以按这个尺寸来做,也可以按原尺寸来做。如果是后者,则需要进行缩放,缩放比例就是 B / A
      

  15.   

    float fAngle = xx;
    mat4 matRotate;
    matRotate.rotateZ(fAngle);
    for(int i=0; i<4; ++i)
    {
         vDests[i] = MatRotate * vSrc[i];
    }vec2 vMax = FindMax(vDest, 4);
    vec2 vMin = FindMin(vDest, 4);
    vec2 vScale = vec2((vMax.x - vMin.x)/fWidth, (vMax.y - vMin.y)/fHeight);
    mat4 matScale;
    matScale.scale(vScale, 1.0f);
    for(int i=0; i<4; ++i)
    {
         vDests[i] = MatScale * Dests[i];
    }
    //投影,光栅化得到最终图像,over,so easy....
      

  16.   

    建议楼主看看 仿射变换!使用OPENCV中的仿射变换很快能达到你的要求!
      

  17.   

        public static Bitmap GenThumbnail(Bitmap imageFrom, int width, int height)
            {
                // 源图宽度及高度 
                int imageFromWidth = imageFrom.Width;
                int imageFromHeight = imageFrom.Height;
                
                // 生成的缩略图实际宽度及高度 
                if (width >= imageFromWidth && height >= imageFromHeight)
                {
                    return imageFrom;
                }
                else
                {
                    // 生成的缩略图在上述"画布"上的位置 
                    int X = 0;
                    int Y = 0;                decimal wpercent = (decimal)width / imageFromWidth;
                    decimal hpercent = (decimal)height / imageFromHeight;
                    if (wpercent > hpercent)
                    {
                        width = (int)(imageFromWidth * hpercent);
                    }
                    else if (wpercent < hpercent)
                    {
                        height = (int)(imageFromHeight * wpercent);
                    }                // 创建画布 
                    using (Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb))
                    {
                        bmp.SetResolution(imageFrom.HorizontalResolution, imageFrom.VerticalResolution);
                        using (Graphics g = Graphics.FromImage(bmp))
                        {                        // 用白色清空 
                            g.Clear(Color.White);                        // 指定高质量的双三次插值法。执行预筛选以确保高质量的收缩。此模式可产生质量最高的转换图像。 
                            g.InterpolationMode = InterpolationMode.HighQualityBicubic;                        // 指定高质量、低速度呈现。 
                            g.SmoothingMode = SmoothingMode.HighQuality;                        // 在指定位置并且按指定大小绘制指定的 Image 的指定部分。 
                            g.DrawImage(imageFrom, new Rectangle(X, Y, width, height), new Rectangle(0, 0, imageFromWidth, imageFromHeight), GraphicsUnit.Pixel);                        return bmp;
                        }
                    }
                }
            }
      

  18.   

    看了一下都没有看明白,但是觉得这位老兄的做法比较好,使用OpenGL吧
    移植性比较高
      

  19.   

    目前很多开源的库都使用了OpenGL,它是一个跨编程语言、跨平台的编程2D和3D的库,使用这个是比较好的。上面某些人的做法不值得推广。
      

  20.   

    自己写的轻量级的ogl 3D管线,需要整形来替代浮点插值,才能达到嵌入下实时刷新~自然没有ogl灵活咯。