Please take a look at the following image:
Setting mask to the rotated image allowed me to achieve white background when image is displayed on the canvas, but it won't be possible to save it with white background or rotate it again. I was wondering - is there a way to do force rotating mechanism to use white colour for background? Or maybe it's possible to merge image with its mask?
Force wxImage::Rotate to produce white background Topic is solved
- eranon
- Can't get richer than this
- Posts: 867
- Joined: Sun May 13, 2012 11:42 pm
- Location: France
- Contact:
Re: Force wxImage::Rotate to produce white background
You don't show any code... When do you draw your image? During OnPaint handler?
[Ind. dev. - wxWidgets 3.0/3.1 under "Win 7 64-bit, TDM64-GCC" + "OS X 10.9, LLVM Clang"]
Re: Force wxImage::Rotate to produce white background
Use SetMaskColor( 255,255,255 ) before rotating and SetMask(false) before saving and you should get the correct result.
Tested with this:
Tested with this:
Code: Select all
::wxInitAllImageHandlers();
const double halfC = M_PI / 180;
wxImage img("d:\\_test.jpg", wxBITMAP_TYPE_JPEG );
img.SetMaskColour(255,255,255);
wxImage img1 = img.Rotate(45.0f * halfC, wxPoint(img.GetWidth()/2, img.GetHeight()/2), false );
img1.SetMask(false);
img1.SaveFile( "d:\\_test_rot1.png", wxBITMAP_TYPE_PNG );
img1.SetMaskColour(255,255,255);
wxImage img2 = img1.Rotate(45.0f * halfC, wxPoint(img1.GetWidth()/2, img1.GetHeight()/2), false );
img2.SetMask(false);
img2.SaveFile( "d:\\_test_rot2.png", wxBITMAP_TYPE_PNG );
Use the source, Luke!
- eranon
- Can't get richer than this
- Posts: 867
- Joined: Sun May 13, 2012 11:42 pm
- Location: France
- Contact:
Re: Force wxImage::Rotate to produce white background
Does a mask is really necessary here, doublemax? Is the interpolating parameter of wxImage::Rotate not enough (unless the fact we have to clear the background if a previous image has been drawn of course, but it's not the question of the op)?
[Ind. dev. - wxWidgets 3.0/3.1 under "Win 7 64-bit, TDM64-GCC" + "OS X 10.9, LLVM Clang"]
Re: Force wxImage::Rotate to produce white background
I don't think the interpolating parameter is relevant here. If the image is rotated, the target image is bigger than the original one, and the empty corners need to be filled with something. By default this is black and the mask color is the only way to change this.
Use the source, Luke!
Re: Force wxImage::Rotate to produce white background
This worked like a charm! Many thanks!Use SetMaskColor( 255,255,255 ) before rotating and SetMask(false) before saving and you should get the correct result.
- eranon
- Can't get richer than this
- Posts: 867
- Joined: Sun May 13, 2012 11:42 pm
- Location: France
- Contact:
Re: Force wxImage::Rotate to produce white background
In theory, I agree with you, doublemax, but in practice in the quick test I written below, when I raise the interpolation flag, it works, while when it's down, I get the black background around:doublemax wrote:I don't think the interpolating parameter is relevant here. If the image is rotated, the target image is bigger than the original one, and the empty corners need to be filled with something. By default this is black and the mask color is the only way to change this.
Code: Select all
// YOU HAVE TO CLICK ONE TIME TO START THE ROTATIONS SEQUENCE
#include "wx/wx.h"
#include <wx/stdpaths.h>
#include <wx/filename.h>
class MinDialog : public wxDialog
{
public:
MinDialog() : wxDialog(NULL, wxID_ANY, wxString("Minimal Dialog"),
wxDefaultPosition, wxSize(800, 800)){
wxString exe_dir = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath();
m_img = wxImage(exe_dir + "/test.png", wxBITMAP_TYPE_PNG);
m_timer = new wxTimer(this);
SetBackgroundColour (*wxBLUE);
ClearBackground();
Connect(m_timer->GetId(), wxEVT_TIMER, wxTimerEventHandler(MinDialog::OnTimer), NULL, this);
Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(MinDialog::OnDown));
Connect(wxEVT_PAINT,(wxObjectEventFunction) &MinDialog::OnPaint);}
private:
wxImage m_img;
wxTimer* m_timer;
void OnDown(wxMouseEvent& event){
wxUnusedVar(event);
m_timer->Start(1000);}
void OnTimer(wxTimerEvent& event){
wxUnusedVar(event);
static int angle = 0;
angle += 45;
// with "false" rather than "true" below, it doesn't work (black around the rotated image)
m_img = m_img.Rotate(angle, wxPoint(m_img.GetWidth()/2, m_img.GetHeight()/2), true);
Refresh(false);}
void OnPaint (wxPaintEvent &){
wxPaintDC dc(this);
dc.DrawBitmap(m_img, 300, 300);}
};
class MinApp : public wxApp
{
bool OnInit(){
wxInitAllImageHandlers();
MinDialog dlg;
dlg.ShowModal();
return false;}
};
DECLARE_APP(MinApp)
IMPLEMENT_APP(MinApp)
- Attachments
-
- test image used in the code above
- test.png (72.95 KiB) Viewed 1870 times
[Ind. dev. - wxWidgets 3.0/3.1 under "Win 7 64-bit, TDM64-GCC" + "OS X 10.9, LLVM Clang"]
Re: Force wxImage::Rotate to produce white background
I think the issue was what happens when you save the rotated image. In one case you will get the rotated image with the "new" parts transparent. But if you want the whole image to be opaque with a white background, you need the other method.
Use the source, Luke!
- eranon
- Can't get richer than this
- Posts: 867
- Joined: Sun May 13, 2012 11:42 pm
- Location: France
- Contact:
Re: Force wxImage::Rotate to produce white background
You're right, doublemax! Saving the rotated images during sequence, it confirms the extra parts are transparents: this explains that
Code: Select all
// Just after rotation in OnTimer()
m_img.SaveFile(wxString::Format("%s/rot_%i.png", m_exe_dir, angle));
- Attachments
-
- rotated with transparency around
- rot_45.png (86.53 KiB) Viewed 1865 times
[Ind. dev. - wxWidgets 3.0/3.1 under "Win 7 64-bit, TDM64-GCC" + "OS X 10.9, LLVM Clang"]