65.9K
CodeProject 正在变化。 阅读更多。
Home

图像压缩器

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.79/5 (14投票s)

2009 年 6 月 18 日

CPOL

3分钟阅读

viewsIcon

47264

downloadIcon

4090

最简单的图像压缩方式。

ImageCompressor_source

引言

人们经常需要通过电子邮件发送图片。由于图像文件的大小,上传这些图片需要很长时间,特别是当网络连接速度较慢时。我一直使用画图工具打开文件,并使用“另存为”功能将图像文件保存为 JPEG 格式。问题在于打开每个文件、另存为以及输入文件名所需的时间。这个小程序解决了这个问题,它使用 MFC 内置类以及非常可靠的 CxImage 类来执行压缩。用户只需要添加源文件夹和目标文件夹,所有图像文件都会被加载和保存,无需其他用户输入。

背景

转换过程完全使用 CxImage 类进行。该类有精简版和完整版两种。CodeProject 网站还提供 详细文章,介绍如何使用 CxImage 类。这并非绝对必要,但可以让你了解实际发生的情况。

Using the Code

这是一个非常简单的基于对话框的应用程序。用户选择源目录,然后选择目标目录。从源目录读取文件,然后在 while 循环中进行转换。要转换的文件必须具有 JPEG、BMP、JPG 或 TIFF 扩展名(所有这些都通过 if 语句完成)。添加了一个进度控制条,并根据转换的文件数量,文件逐个推进。成功转换的文件显示在一个窗口中,而所有未转换的文件被标记为错误,然后在第二个窗口中显示。一个滑块控件选择要实现的压缩比。所有转换都借助 CxImage 类完成,该类加载图像、设置 JPEG 质量,然后将文件保存到用户选择的目录中。还添加了两个列表框,一个显示成功转换的文件结果,另一个显示未转换的文件名。

源目录和目标目录使用 BROWSEINFO 结构选择,如下所示

BROWSEINFO bi = { 0 };
bi.lpszTitle = _T("Select path for Source Directory");
bi.ulFlags = BIF_USENEWUI;
LPITEMIDLIST pidl = SHBrowseForFolder ( &bi );
if ( pidl != 0 )
{
    // get the name of the folder
    TCHAR path[MAX_PATH];
    if ( SHGetPathFromIDList ( pidl, path ) )
    {
        _tprintf ( _T("Selected Folder: %s\n"), path );
    }
    m_SourceDir = path;
    UpdateData(FALSE);

    // free memory used
    IMalloc * imalloc = 0;
    if ( SUCCEEDED( SHGetMalloc ( &imalloc )) )
    {
        imalloc->Free ( pidl );
        imalloc->Release ( );
    }

单击“开始”按钮后,首先计算要转换的文件数量,并根据计算出的文件数量生成文件名。生成的文件名存储在 CStringArray 对象中。

CString numb;
CStringArray filenames;
CString add = "\\image";
CString add1 = ".jpg";
for (int x=1;x<=n;x++)
{
    numb.Format("%d",x);
    CString fname = m_DestDir+add+numb+add1;
    filenames.Add(fname);
}

使用 CFileFind 类对象,选择的源目录然后在 while 循环中使用,以遍历每个文件,并根据已经生成的文件名,赋予文件名。进度条逐个文件移动,最终任何生成的错误都会在列表框中列出,以及成功转换的文件名。

int no = filenames.GetCount();      // getting total number of file names from CStringArray object
CString filename;                   // making sure a valid file extension is selected
m_ProgressBar.SetRange(0,n);
m_ProgressBar.SetStep(1);
BOOL bS1 = finder.FindFile(_T(m_SourceDir+CString("\\*.*")));
int num=0;
m_Slider = m_SliderValue.GetPos();
while(bS1)
{
    bS1 = finder.FindNextFile();
    if(finder.IsDots() || finder.IsDirectory())
        continue;
    filename = finder.GetFileTitle();   // getting the filename used in the following if statement
    if(num==no)                         // if true we have converted all the files
        break;      
    if ((filename+CString(".jpg") == finder.GetFileName()) || 
        (filename+CString(".bmp") == finder.GetFileName()) ||
        (filename+CString(".jpeg") == finder.GetFileName()) || 
        (filename+CString(".tiff") == finder.GetFileName()))
    {                 
        image.Load(finder.GetFilePath(),0); // loading file into memory using CxImage Class
        image.SetJpegQuality(m_Slider);           // setting the compression ratio
        image.Save(filenames.GetAt(num),CXIMAGE_FORMAT_JPG);  // saving the file using
                                                              // already generated filename
        m_ConvFiles.AddString(filename+CString(" -->> Converted successfully"));
        m_ProgressBar.StepIt();
        ++num;
    }
    else
    {
        m_Errors.AddString(finder.GetFileName()+CString(" -->> File format Invalid"));
        continue;
    }
}

关注点

该应用程序使用 CxImage 类来实现所需的压缩。

历史

版本 1.0。

© . All rights reserved.