【问题标题】:C++ - save image from form to fileC++ - 将图像从表单保存到文件
【发布时间】:2016-02-18 15:13:23
【问题描述】:

我是 Windows 窗体应用程序编程的新手。我想捕获我的 Windows 窗体(使用 CaptureScreen() 函数)并通过单击使用 SaveFileDialog 的按钮将其保存到文件中。这是我的代码:

private: System::Void CaptureScreen() 
{
    Drawing::Graphics^ myGraphics = this->CreateGraphics();
    memoryImage = gcnew Drawing::Bitmap(Size.Width, Size.Height, myGraphics);
    Drawing::Graphics^ memoryGraphics = Drawing::Graphics::FromImage(memoryImage);
    memoryGraphics->CopyFromScreen(this->Location.X, this->Location.Y, 0, 0, this->Size);
}

private: System::Void btnSave_Click(System::Object^  sender, System::EventArgs^  e) 
{
    SaveFileDialog^ saveDiag2 = gcnew SaveFileDialog();
    saveDiag2->Filter = "Dateityp PNG (*.PNG)|*.PNG|All files (*.*)|*.*";
    saveDiag2->FilterIndex = 1;
    saveDiag2->RestoreDirectory = true;
    if (saveDiag2->ShowDialog() == System::Windows::Forms::DialogResult::OK)
    {
        String^ savePath = saveDiag2->FileName;
        if (saveDiag2->OpenFile() != nullptr)
        {
            try
            { 
                CaptureScreen();
                if (memoryImage != nullptr)
                {
                    memoryImage->Save(savePath, Imaging::ImageFormat::Png);
                }
            }
            catch (Exception^)
            {
                MessageBox::Show("There was a problem saving the file."
                    "Check the file permissions.");
            }
        }
    }
}

我总是显示异常。我做错了什么?

【问题讨论】:

  • C++-CLI 是此代码的正确标记,还为 Windows 窗体添加了标记。
  • 您能否显示异常内容,它可能表明您出了什么问题。您也可以在 try 块的开头放置一个断点以进行调试
  • 那是非常糟糕的错误处理代码,永远不会显示“它不起作用”的消息。这对任何人都没有帮助,对你也没有帮助。使用异常对象的 ToString() 方法。你的代码丢失了delete memoryImage; 如果你不这样做,那么文件将保持锁定状态,尝试覆盖它将会失败。

标签: winforms visual-c++ c++-cli


【解决方案1】:

汉斯·帕桑特是对的。您应该处置 IDisposible 对象。在 C++ CLI 中,您可以借助 msclr::auto_handle 智能指针来完成。

#include <msclr/auto_handle.h>

private: System::Void CaptureScreen() 
         {
             msclr::auto_handle<Drawing::Graphics> myGraphics(this->CreateGraphics());
             memoryImage = gcnew Drawing::Bitmap(Size.Width, Size.Height, myGraphics.get());
             msclr::auto_handle<Drawing::Graphics> memoryGraphics(Drawing::Graphics::FromImage(memoryImage));
             memoryGraphics->CopyFromScreen(this->Location.X, this->Location.Y, 0, 0, this->Size);
         }

您还可以从异常对象中检索有用的信息:

    catch (Exception^ exception)
    {
        MessageBox::Show("There was a problem saving the file: " + exception->ToString(),
            "Check the file permissions.");
    }

【讨论】:

  • 感谢您的回答。我在@Hans Passant 建议的错误处理代码之后添加了delete memoryImage。 @Dmitriy 异常对象现在产生以下错误:System.Runtime.InteropServices.ExternalException (0x80004005): Error in GDI+.at System.Drawing.Image.Save(String filename, ImageCodecInfo Encoder, EncoderParameters encoderParams)at System.Drawing.Image.Save(String filename, Imageformat Format)at btnSave_Click(Object Sender, EventArgs e) in Programm.h:Row 548. 是因为保存在网络文件夹上而发生的错误。在这我应该如何处理呢?
  • 您可以通过保存到本地驱动器轻松检查。您还可以检查权限。也看看here - 第二个答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-31
  • 2021-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多