VB6.0 GDI 保存JPG图片质量差问题

cnewerPlus 2016-07-23 11:29:37
我在做一个图片处理软件。涉及图片压缩,格式转换等。
开发环境,WinXP+VB6.0,运用了GDI
用户在WinXP环境下,一切正常。

在Win7以上系统时,在VB6.0开发境中编译(包括全编译)时,仍然一切正常。
但生产exe文件后,当图片保存为JPG时,图片质量变得很差。如附图样子。
但是保存为BMP时没有这个问题。

我理解是不是操作系统的哪里不一样,影响了JPG保存的过程,
保存为JPG函数的函数如下:


'*************************************************************************
'** 函 数 名 : funSaveImgToFile
'** 输 入 : pic(StdPicture) - 图象句柄
'** : FileName(String) - 保存路径
'** : Quality(Byte) - JPG图象质量
'** : TIFF_ColorDepth(Long) - TTF格式的颜色深度
'** : TIFF_Compression(Long) - TTF格式的压缩比
'** 输 出 : 成功与否
'** 功能描述 : 把图象保存为JPG、TIFF、PNG、GIF、BMP格式
'*************************************************************************
Public Function funSaveImgToFile(ByVal pict As StdPicture, ByVal FileName As String, ByVal PicType As String, _
Optional ByVal Quality As Byte = 100, _
Optional ByVal TIFF_ColorDepth As Long = 24, _
Optional ByVal TIFF_Compression As Long = 6) As Boolean
Dim tSI As GdiplusStartupInput
Dim lRes As Long
Dim lGDIP As Long
Dim lBitmap As Long
Dim aEncParams() As Byte

' 初始化 GDI+
tSI.GdiplusVersion = 1
lRes = GdiplusStartup(lGDIP, tSI, 0)
If lRes = 0 Then ' 从句柄创建 GDI+ 图像
lRes = GdipCreateBitmapFromHBITMAP(pict.handle, 0, lBitmap)
If lRes = 0 Then
Dim tJpgEncoder As GUID
Dim tParams As EncoderParameters '初始化解码器的GUID标识
Select Case LCase(PicType) '防止前面写文件格式是把小写搞成大写,如果是就转为小写字
Case "jpg"
CLSIDFromString StrPtr("{557CF401-1A04-11D3-9A73-0000F81EF32E}"), tJpgEncoder
tParams.Count = 1 ' 设置解码器参数
With tParams.Parameter ' Quality
CLSIDFromString StrPtr("{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"), .GUID ' 得到Quality参数的GUID标识
.NumberOfValues = 1
.type = 4
.Value = VarPtr(Quality)
End With
ReDim aEncParams(1 To Len(tParams))
Call CopyMemory(aEncParams(1), tParams, Len(tParams))
Case "png"
CLSIDFromString StrPtr("{557CF406-1A04-11D3-9A73-0000F81EF32E}"), tJpgEncoder
ReDim aEncParams(1 To Len(tParams))
Case "gif"
CLSIDFromString StrPtr("{557CF402-1A04-11D3-9A73-0000F81EF32E}"), tJpgEncoder
ReDim aEncParams(1 To Len(tParams))
Case "tiff"
CLSIDFromString StrPtr("{557CF405-1A04-11D3-9A73-0000F81EF32E}"), tJpgEncoder
tParams.Count = 2
ReDim aEncParams(1 To Len(tParams) + Len(tParams.Parameter))
With tParams.Parameter
.NumberOfValues = 1
.type = 4
CLSIDFromString StrPtr("{E09D739D-CCD4-44EE-8EBA-3FBF8BE4FC58}"), .GUID ' 得到ColorDepth参数的GUID标识
.Value = VarPtr(TIFF_Compression)
End With
Call CopyMemory(aEncParams(1), tParams, Len(tParams))
With tParams.Parameter
.NumberOfValues = 1
.type = 4
CLSIDFromString StrPtr("{66087055-AD66-4C7C-9A18-38A2310B8337}"), .GUID ' 得到Compression参数的GUID标识
.Value = VarPtr(TIFF_ColorDepth)
End With
Call CopyMemory(aEncParams(Len(tParams) + 1), tParams.Parameter, Len(tParams.Parameter))
End Select
lRes = GdipSaveImageToFile(lBitmap, StrPtr(FileName), tJpgEncoder, aEncParams(1)) '保存图像
GdipDisposeImage lBitmap ' 销毁GDI+图像
End If
GdiplusShutdown lGDIP '销毁 GDI+
End If
Erase aEncParams
If lRes Then
funSaveImgToFile = False
Else
funSaveImgToFile = True
End If
Exit Function
End Function


处理出的图片样子:


求大神帮忙。。所有分数奉送。
...全文
2960 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2016-07-28
  • 打赏
  • 举报
回复
仅供参考:
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <windows.h>
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;
wchar_t formats[5][11]={
    L"image/bmp",
    L"image/jpeg",
    L"image/gif",
    L"image/tiff",
    L"image/png",
};
wchar_t exts[5][5]={
    L".bmp",
    L".jpg",
    L".gif",
    L".tif",
    L".png",
};
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {
   UINT  num = 0;          // number of image encoders
   UINT  size = 0;         // size of the image encoder array in bytes
   ImageCodecInfo* pImageCodecInfo = NULL;
   GetImageEncodersSize(&num, &size);
   if(size == 0) return -1;  // Failure
   pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
   if(pImageCodecInfo == NULL) return -1;  // Failure
   GetImageEncoders(num, size, pImageCodecInfo);
   for (UINT j = 0; j < num; ++j) {
      if ( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) {
         *pClsid = pImageCodecInfo[j].Clsid;
         free(pImageCodecInfo);
         return j;  // Success
      }
   }
   free(pImageCodecInfo);
   return -1;  // Failure
}
int wmain(int argc,wchar_t *argv[]) {
    int r=1;
    if (argc<4) {
    USAGE:
        wprintf(L"%s srcimg.{bmp|jpg|gif|tif|png|wmf|emf|ico}  desimg.{bmp|jpg|gif|tif|png}  angle\n",argv[0]);
        return r;
    }
    int i;
    for (i=0;i<5;i++) {
        if (0==_wcsicmp(argv[1]+wcslen(argv[1])-4,exts[i])) break;
    }
    if (i>=5) goto USAGE;
    for (i=0;i<5;i++) {
        if (0==_wcsicmp(argv[2]+wcslen(argv[2])-4,exts[i])) break;
    }
    if (i>=5) goto USAGE;
    GdiplusStartupInput gdiplusstartupinput;
    ULONG_PTR gdiplustoken;
    GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);
    {
        Image img(argv[1]);
        if (Ok==img.GetLastStatus()) {
            UINT height = img.GetHeight();
            UINT width  = img.GetWidth();
            REAL angle;
            if (1==swscanf_s(argv[3],L"%f",&angle)) {
                REAL size;
                size=(REAL)sqrt(1.0*width*width+1.0*height*height);
                Matrix mat;
                mat.Translate(size / -2.0f, size / -2.0f);
                mat.Rotate(-angle, MatrixOrderAppend);
                mat.Translate(size / 2.0f, size / 2.0f, MatrixOrderAppend);
                PointF pfTL((size-width)/2.0f      ,(size-height)/2.0f       );
                PointF pfTR((size-width)/2.0f+width,(size-height)/2.0f       );
                PointF pfBL((size-width)/2.0f      ,(size-height)/2.0f+height);
                PointF pfBR((size-width)/2.0f+width,(size-height)/2.0f+height);
                Graphics tgp(&img);
                Bitmap bmp((UINT)size,(UINT)size,&tgp);//Let bmp Resolution equal to img Resolution
                Graphics gp(&bmp);
                gp.SetTransform(&mat);
                gp.DrawImage(&img,pfTL);
                REAL xmin,ymin,xmax,ymax,x,y,rw,rh;
                mat.TransformPoints(&pfTL);
                xmin=xmax=pfTL.X;
                ymin=ymax=pfTL.Y;
                mat.TransformPoints(&pfTR);
                if (xmin>pfTR.X) xmin=pfTR.X;
                if (xmax<pfTR.X) xmax=pfTR.X;
                if (ymin>pfTR.Y) ymin=pfTR.Y;
                if (ymax<pfTR.Y) ymax=pfTR.Y;
                mat.TransformPoints(&pfBL);
                if (xmin>pfBL.X) xmin=pfBL.X;
                if (xmax<pfBL.X) xmax=pfBL.X;
                if (ymin>pfBL.Y) ymin=pfBL.Y;
                if (ymax<pfBL.Y) ymax=pfBL.Y;
                mat.TransformPoints(&pfBR);
                if (xmin>pfBR.X) xmin=pfBR.X;
                if (xmax<pfBR.X) xmax=pfBR.X;
                if (ymin>pfBR.Y) ymin=pfBR.Y;
                if (ymax<pfBR.Y) ymax=pfBR.Y;
                x=xmin;
                y=ymin;
                rw=xmax-x;
                rh=ymax-y;
                Bitmap* clone;
                clone = bmp.Clone(x,y,rw,rh,PixelFormat24bppRGB);//bmp.GetPixelFormat()
                CLSID encoderClsid;
                if (0<=GetEncoderClsid(formats[i],&encoderClsid)) {
                    if (Ok==clone->Save(argv[2],&encoderClsid)) {
                        wprintf(L"OK to %s  %s  %s  %s\n",argv[0],argv[1],argv[2],argv[3]);
                        r=0;
                    } else {
                        wprintf(L"Error to save %s\n",argv[2]);
                        r=4;
                    }
                } else {
                    wprintf(L"Error to GetEncoderClsid(%s,...)\n",formats[i]);
                    r=3;
                }
                delete clone;
            } else {
                wprintf(L"Error to get angle %s\n",argv[3]);
                r=2;
            }
        } else {
            wprintf(L"Error to load %s\n",argv[1]);
            r=5;
        }
    }
    GdiplusShutdown(gdiplustoken);
    return r;
}
舉杯邀明月 2016-07-27
  • 打赏
  • 举报
回复
引用 6 楼 cnewerPlus 的回复:
[quote=引用 5 楼 zhao4zhong1 的回复:] 我倒觉得色斑版的图片更艺术更朦胧。
我们谈技术,您给我们谈艺术,太高大上了……[/quote] 那我给你谈的“技术问题”,你又视而不见?
cnewerPlus 2016-07-27
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
我倒觉得色斑版的图片更艺术更朦胧。
我们谈技术,您给我们谈艺术,太高大上了……
赵4老师 2016-07-27
  • 打赏
  • 举报
回复
我倒觉得色斑版的图片更艺术更朦胧。
舉杯邀明月 2016-07-25
  • 打赏
  • 举报
回复
引用 3 楼 cnewerPlus 的回复:
谢谢楼上支持。参数值我们都是默认100的。 昨天我按照“”P代码“”形式输出exe,就没有了这个问题。
我的是编译成本机代码的。 你也可以编译成本机代码,在别的计算机上运行试一下,看是不是你的系统有什么问题。 瘟到死系统,有一些奇葩问题是很难说清楚原因的。
cnewerPlus 2016-07-25
  • 打赏
  • 举报
回复
谢谢楼上支持。参数值我们都是默认100的。
昨天我按照“”P代码“”形式输出exe,就没有了这个问题。
cnewerPlus 2016-07-23
  • 打赏
  • 举报
回复
而且为什么在开发环境中运行就没问题呢????急啊
舉杯邀明月 2016-07-23
  • 打赏
  • 举报
回复 1
这段代码,我在IDE下运行、编译后运行,都是没有问题的。 我传的“品质”为80,转换效果感觉很好,在10以下时,开始产生“色斑”现象。 楼主是不是代码有点什么问题,编译后的“品质”参数值太低了? 我的运行环境是: Win10 专业版64位,VB6/SP6简体中文企业版。

1,486

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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