Page 1 of 2

как рисовать текст не затирая фон?

Posted: Tue Apr 10, 2018 1:57 pm
by cutecode
Пытаюсь создать штамп электронной подписи, но текст почемуто выглядит какимто грязным.
Цвет фона установлен красным. Текст должен быть чисто синим, а он красносиний

Помогите как рисовать текст красиво

Code: Select all

bool create_shtamp(wxString& szPathToFile, wxString &szOwner, wxString &szSerial, wxString &szIshure, wxString &szD1, wxString &szD2)
{
	wxRect rec(0, 0, 900, 200);
	wxBitmap bitmap(rec.GetWidth(), rec.GetHeight());
	wxMemoryDC dc;
	dc.SelectObject(bitmap);
		
	dc.SetBackground(*wxBLUE_BRUSH);
	dc.Clear();

	dc.SetPen(*wxRED_PEN);
	dc.SetBrush(*wxRED_BRUSH);
	dc.DrawRectangle(1, 1, rec.GetWidth() - 2, rec.GetHeight() - 2);

	wxFont Font(wxFontInfo(8).Family(wxFONTFAMILY_DEFAULT).Bold().FaceName(TrunslateMyFontFaceNames(L"Arial")));

	dc.SetFont(Font);

	dc.SetBackgroundMode(wxPENSTYLE_TRANSPARENT);
	
	dc.SetBackground(*wxRED_BRUSH);

	dc.SetTextForeground(*wxBLUE);
	dc.SetTextBackground(*wxRED);

	dc.DrawText(szOwner, 10, 10);
	dc.DrawText(szSerial, 10, 35);
	dc.DrawText(szIshure, 10, 70);

	dc.SelectObject(wxNullBitmap);

	// Convert the bitmap to an image
	wxImage image = bitmap.ConvertToImage();
	// Set the mask color to red
	image.SetMaskColour(255, 0, 0);
	image.SaveFile(szPathToFile, wxBITMAP_TYPE_PNG);

	return true;
}

Code: Select all

		wxString sz00 = L"e:\\1.png";
		wxString sz1 = L"Георгиевская стоматологическая поликлиника";
		wxString sz2 = L"01fa5a8bae6c238de7118973c43ab5b8";
		wxString sz3 = L" ГКУ СК Краевой центр информтехнологий";
		wxString sz4 = L"01.1.2017";
		wxString sz5 = L"01.12.2017";
		create_shtamp(sz00, sz1, sz2, sz3, sz4, sz5);

Re: как рисовать текст не затирая фон?

Posted: Tue Apr 10, 2018 3:28 pm
by ONEEYEMAN
Dobrogo vremeni sutok,
Kto vyzyvaet create_shtamp() funkciju?

Kstati vygljadit eto ochen pohoge na nastojaschuju pechat'... ;-)

Re: как рисовать текст не затирая фон?

Posted: Tue Apr 10, 2018 3:36 pm
by cutecode
хм, внизу же указан вызов этой функции

Code: Select all

      wxString sz00 = L"e:\\1.png";
      wxString sz1 = L"Георгиевская стоматологическая поликлиника";
      wxString sz2 = L"01fa5a8bae6c238de7118973c43ab5b8";
      wxString sz3 = L" ГКУ СК Краевой центр информтехнологий";
      wxString sz4 = L"01.1.2017";
      wxString sz5 = L"01.12.2017";
      create_shtamp(sz00, sz1, sz2, sz3, sz4, sz5);

Re: как рисовать текст не затирая фон?

Posted: Tue Apr 10, 2018 4:45 pm
by ONEEYEMAN
Etot kod iz obrabotchika EVT_PAINT?

Re: как рисовать текст не затирая фон?

Posted: Tue Apr 10, 2018 4:56 pm
by cutecode
нет я просто создаю свой PNG файл

Re: как рисовать текст не затирая фон?

Posted: Tue Apr 10, 2018 5:01 pm
by ONEEYEMAN
Ne sovsem ponjal otvet.
Eto znachit chto etot shtamp zapisyvaetsja v PNG fajl? On ne otrisovyvaetsja na ekrane?

Po moemu v primere image pokazano kak sozdavat svoj bitmap fajl. Mogu oshibatsja...

Re: как рисовать текст не затирая фон?

Posted: Tue Apr 10, 2018 5:19 pm
by cutecode
да, мне надо создать свой файл *.png, без отображения его на экране.
создается временный DC, и его содержимое сохраняется в файл.

Мне надо как то так

Re: как рисовать текст не затирая фон?

Posted: Tue Apr 10, 2018 9:40 pm
by ONEEYEMAN
Esche ideja - objekt wxFont sozdaetsja normalno? IsOK vozvraschaet "TRUE"?
A esche ja ne znaju - moget byt wxMask dlja PNG ne poddergivaetsja?

Re: как рисовать текст не затирая фон?

Posted: Tue Apr 10, 2018 10:04 pm
by doublemax
The problem is that the mask is only 1 bit and it will mask only the pixels that are 100% red. But because the text is drawn with anti-aliasing you get pixels that are a mix of red and blue and those will not get masked.

What you need to do:

After drawing the text, convert the wxBitmap to a wxImage.
Add an Alpha channel to the image.
Iterate over all pixels and calculate an alpha value based on the pixel color
(Assume you draw black text and a white background and you get a pixel value of (127,127,127), then you know that the pixel should be black, but with an alpha value of 127).

Re: как рисовать текст не затирая фон?

Posted: Tue Apr 10, 2018 10:49 pm
by cutecode
ХМ, спасибо doublemax

никогда не работал с "альфа ченл", буду разбираться.

Кстати, я попробовал заменить красный фон на белый, и шрифт как то по веселее стал отображаться

Re: как рисовать текст не затирая фон?

Posted: Wed Apr 11, 2018 5:39 am
by doublemax
If you "stamp" this onto a light background, it will look fine. But if you stamp this on a black background, you will see white edges that look wrong.

Re: как рисовать текст не затирая фон?

Posted: Wed Apr 11, 2018 6:45 am
by cutecode
Мне альфа надо эксперементально вычислять, для каждого RGB отличного от (0, 0, 255)?
А то теперь шрифт стал ну очень жирный

Code: Select all

	int width = image.GetWidth();
	int height = image.GetHeight();

	if(!image.HasAlpha())
	    image.SetAlpha();

	for(int x=0; x<width; x++)
	{
	    for(int y=0; y<height; y++)
	    {
	        int red = image.GetRed(x, y);
	        int green = image.GetGreen(x, y);
	        int blue = image.GetBlue(x, y);

	        if(red == 0 && green == 0 && blue == 255)
	        {
                image.SetAlpha(x, y, wxIMAGE_ALPHA_OPAQUE);
                continue;
            }
	        else if(red == 255 && green == 255 && blue == 255)
                image.SetAlpha(x, y, wxIMAGE_ALPHA_TRANSPARENT);
            else
            {
                image.SetRGB(x, y, 0, 0, 255);
                image.SetAlpha(x, y, 200);
            }
	    }
	}

Re: как рисовать текст не затирая фон?

Posted: Wed Apr 11, 2018 9:09 am
by doublemax
That's not right.

The calculation is easiest, if you draw in blue onto a black background, because then the background pixels are (0,0,0).

For all pixels:
Set alpha to blue component.
if( blue component is > 0 ) Set blue component to 255.

Re: как рисовать текст не затирая фон?

Posted: Wed Apr 11, 2018 7:54 pm
by doublemax
Tested and working code:

Code: Select all

::wxInitAllImageHandlers();

wxBitmap bmp(320,70,32);
wxMemoryDC mdc( bmp );
mdc.SetPen( *wxBLACK );
mdc.SetBrush( *wxBLACK );
mdc.DrawRectangle( wxRect(mdc.GetSize()) );

mdc.SetTextBackground( *wxBLACK );
mdc.SetTextForeground( *wxBLUE );

wxFont f(28, wxFONTFAMILY_ROMAN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("Lucida Sans Unicode"));
mdc.SetFont( f );

mdc.DrawText( "Hallo wxWidgets", 10, 10 );
mdc.SelectObject( wxNullBitmap );

bmp.SaveFile( "d:\\_text1.png", wxBITMAP_TYPE_PNG );

wxImage img = bmp.ConvertToImage();
img.SetAlpha();

unsigned char *data = img.GetData();
unsigned char *alpha = img.GetAlpha();

unsigned long pixelcount = img.GetWidth() * img.GetHeight();
for( long i=0; i<pixelcount; i++ )
{
  unsigned char blue = data[2];
  *alpha++ = blue;
  if( blue > 0 )
    data[2] = 255;

  data += 3;
}
img.SaveFile( "d:\\_text2.png", wxBITMAP_TYPE_PNG );

Re: как рисовать текст не затирая фон?

Posted: Wed Apr 11, 2018 8:52 pm
by cutecode
спасибо за ваше время.
вставил в свой код, теперь гараздо красивее стало.
особенно на черном фоне