Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: IPicture::Render , непонятная проблема  (Прочитано 32594 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 02-12-2008 12:44 » 

данная процедура выводит картинку из файла в CBitmap. Проблема странная - почему то не рисуется самая верхняя строчка пикселов, а справа наоборот пририсовывается лишняя колонка (и туда копируется последняя правая колонка)

(VC++6 , MFC)

Код:
#include <atlconv.h>

...
...

//вывести пикселы формата файла бмп на бмп
//pFurtherDC - DC, на который предполагается вывод бмп
bool DrawBitmapPixelsFromFileToBMP(CDC* pFurtherDC,CBitmap* pBMP,const char* pchFullFilePath,int *pW,int *pH)
{
bool result=false;
CDC tempDC;
CBitmap *oldbmp=0;

if(!pW || !pH)return false;

*pW=0;
*pH=0;

IPicture* pPic=0;

result=false;
for(;;)
{
IPicture* ptmpPic=0;
USES_CONVERSION;//#include <atlconv.h>
HRESULT hr;

hr= ::OleLoadPicturePath(const_cast<LPOLESTR>(T2COLE(pchFullFilePath)),0,0,0,IID_IPicture,reinterpret_cast<void **>(&ptmpPic));

if(hr==S_OK && ptmpPic)
{
pPic=ptmpPic;
}
else
{
break;
}

OLE_XPOS_HIMETRIC cxSrc;
OLE_YPOS_HIMETRIC cySrc;

if(S_OK!=pPic->get_Width(&cxSrc))break;
if(S_OK!=pPic->get_Height(&cySrc))break;

*pW=cxSrc/26;
*pH=cySrc/26;

if(!tempDC.CreateCompatibleDC(pFurtherDC))break;
pBMP->DeleteObject();
if(!pBMP->CreateCompatibleBitmap(pFurtherDC,*pW,*pH))break;
oldbmp=tempDC.SelectObject(pBMP);

//рисуем

//ПОЧЕМУ ТО НЕ РИСУЕТСЯ САМАЯ ВЕРХНЯЯ СТРОЧКА ПИКСЕЛОВ
//А СПРАВА НАОБОРОТ ПРИРИСОВЫВАЕТСЯ ЛИШНЯЯ (И ТУДА КОПИРУЕТСЯ ПОСЛЕДНЯЯ ПРАВАЯ)
if(S_OK !=pPic->Render(
tempDC.GetSafeHdc(),
0,
0+*pH,
*pW,
-*pH,//переворачиваем по вертикали
0,0,cxSrc,cySrc,0))break;

result=true;

///
break;
}

if(pPic)
{
pPic->Release();
pPic=0;
}

if(oldbmp)
{
tempDC.SelectObject(oldbmp);
}

return result;
}

а в чём проблема то ? Не могу понять
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 02-12-2008 12:57 » 

а, забыл уточнить, пририсовку справа видно, если тут

в if(!pBMP->CreateCompatibleBitmap(pFurtherDC,*pW,*pH))break;

нарочно увеличить размер битмапа
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #2 : 02-12-2008 13:28 » 

А что за "переворачиваем по вертикали"? Ты её ещё и вращаешь что ли?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 02-12-2008 17:19 » 

Джон, а оно вверх ногами туда чпокается почему то ) По аналогии с bitblt я туда минус - и оно перевернулось

на не перевёрнутом та же проблема, кстати
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 03-12-2008 05:56 » 

источник проблемы я нашёл: соотношение между единицами, используемыми в
OLE_XPOS_HIMETRIC cxSrc;
OLE_YPOS_HIMETRIC cySrc;
и размерами пикселов

методом научного тыка определил величину, которая подозрительно напоминает дюйм ))
Код:
//вывести пикселы формата файла бмп на бмп
//pFurtherDC - DC, на который предполагается вывод бмп
bool CFileMinder::DrawBitmapPixelsFromFileToBMP(CDC* pFurtherDC,CBitmap* pBMP,const char* pchFullFilePath,int *pW,int *pH)
{
bool result=false;
CDC tempDC;
CBitmap *oldbmp=0;

if(!pW || !pH)return false;

*pW=0;
*pH=0;

IPicture* pPic=0;

result=false;
for(;;)
{
IPicture* ptmpPic=0;
USES_CONVERSION;//#include <atlconv.h>
HRESULT hr;

hr= ::OleLoadPicturePath(const_cast<LPOLESTR>(T2COLE(pchFullFilePath)),0,0,0,IID_IPicture,reinterpret_cast<void **>(&ptmpPic));

if(hr==S_OK && ptmpPic)
{
pPic=ptmpPic;
}
else
{
break;
}

OLE_XPOS_HIMETRIC cxSrc;
OLE_YPOS_HIMETRIC cySrc;

if(S_OK!=pPic->get_Width(&cxSrc))break;
if(S_OK!=pPic->get_Height(&cySrc))break;


enum
{
e_div_1000 = 1000,
e_X_1000 = 25400,
e_Y_1000 = 25400,
};

*pW=((float)cxSrc)*e_div_1000/e_X_1000;
*pH=((float)cySrc)*e_div_1000/e_Y_1000;

if(!tempDC.CreateCompatibleDC(pFurtherDC))break;
pBMP->DeleteObject();
if(!pBMP->CreateCompatibleBitmap(pFurtherDC,*pW,*pH))break;
oldbmp=tempDC.SelectObject(pBMP);

//рисуем

//рисунок будет перевёрнут!
//переворачивать потом в StretchBlt или BitBlt , указав высоту приёмника отрицательной
if(S_OK !=pPic->Render(tempDC.GetSafeHdc(),
0,
0,
*pW,
*pH,
0,
0,
cxSrc+e_X_1000/e_div_1000,
cySrc+e_Y_1000/e_div_1000,0)
)break;

result=true;

///
break;
}

if(pPic)
{
pPic->Release();
pPic=0;
}

if(oldbmp)
{
tempDC.SelectObject(oldbmp);
}

return result;
}

в этом случае рисунок весь виден (перевернуть позже - не проблема) , однако искажение имеется - например рисунок шире или выше на 1 пиксел от оригинала

Как правильно делать перевод величин ?
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 03-12-2008 10:56 » 

Лёш, а вот с этим сравнивал?
https://forum.shelek.ru/index.php/topic,5773.msg98390.html#msg98390
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 03-12-2008 11:50 » 

Джон, сравнил, число я правильно подобрал, оказывается ))

Сделал всё как по ссылке - отличия нету (( Щас ухожу, ещё ночью поразбираюсь
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #7 : 03-12-2008 12:33 » 

Насколько я помню я тот код из живого проекта выдрал, всё рабочее было. Я с gdi уже давно "завязал", ща если что-то с графикой, то gdi+, опять же до-диез с ней работает. Там отображение картинок упрощено до невозможности.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 03-12-2008 17:19 » 

gdi+ - а оттуда что можно в 6-й студии поюзать ? И как ?
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 04-12-2008 04:57 » 

Лёш, да всё можно использовать. gdi+ это навороченная надстройка над gdi.

1. Ставишь SDK (если ещё не стоит)

2. В студии настраиваешь папки для .h .lib из неё и ставишь! их на первое место - раньше родных.

3. Инклудишь файл из прицепа (у родного проблемы с макросом DEBUG_NEW для ловли утечек)

4. и фсё

Код:
void CMyTestView::OnDraw(CDC* pDC)
{
CMyTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

Graphics *graphics = Graphics::FromHDC(pDC->m_hDC);

graphics->SetSmoothingMode(SmoothingModeNone);
graphics->SetPageUnit(UnitMillimeter);

graphics->ScaleTransform(1.0f, 1.0f);
graphics->SetPageScale(0.001f);
graphics->SetPixelOffsetMode(PixelOffsetModeHalf);

Color cl = Color::Red;
Brush *pBrush = new SolidBrush(cl);

Rect rc = Rect(10000,10000,50000, 50000); // значения в микрометрах

graphics->FillRectangle(pBrush, rc);

delete pBrush;
}

А дальше уже MSDN по gdi+ объектам.

* GdiplusH.h (4.38 Кб - загружено 934 раз.)
« Последнее редактирование: 04-12-2008 04:59 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #10 : 04-12-2008 05:21 » 

Кстати о птичках, вот так показываешь картинки...

Код:
void CMyTestView::OnDraw(CDC* pDC)
{
CMyTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

Graphics *graphics = Graphics::FromHDC(pDC->m_hDC);
graphics->SetSmoothingMode(SmoothingModeNone);
graphics->SetPageUnit(UnitPixel);
graphics->ScaleTransform(1.0f, 1.0f);
graphics->SetPageScale(1.0f);
graphics->SetPixelOffsetMode(PixelOffsetModeHalf);

Image image(L"d:\\my_photo.jpg");
if(image.GetLastStatus()==Ok)
{
UINT uiWidth = image.GetWidth();
UINT uiHeight = image.GetHeight();
graphics->DrawImage(&image, 10, 10, uiWidth, uiHeight);
}
}
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 04-12-2008 05:21 » 

1 буду искать и качать ))

2 до этого доберёмся после кача. Но, то есть, выходит просто типа патча - заменятся некоторые родные файлы студии ?

3 этот файл с дистрибутиве должен быть по идее тоже? То есть его заменить надо будет

---------
ночером буду пробовать
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #12 : 04-12-2008 05:27 » 

Хе? SDK платформа - весчь номер 1, ставится сразу же после студии. Никакой не патч! В списке папок для библиотек и включений надо указать на первом месте, чтобы её файлы интертрепировались в первую очередь, иначе получишь конфликты.

А .h файл это просто решение проблемы с отловлей утечки памяти (макрос нельзя инклудить в файлы с использованием оператора new для gdi+ объектов), найдено где-то в инете. Если тебе это не требуется, то можешь инклудить стандартный gdiplus.h и всё.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 04-12-2008 05:32 » 

а если использую прицепленный хедер - то нет этого ограничения ? )
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #14 : 04-12-2008 11:30 » 

В этом хидере сделан workaround и можно использовать макрос DEBUG_NEW в .срр файлах где создаются новые объекты gdi+, например new Brush.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 04-12-2008 11:33 » 

но, в принципе, это же только при отладке важно ? Если утечек нету
Записан

АлексейК
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 04-12-2008 12:11 » 

А можно на одном CDC рисовать с помощью gdi и gdi+ одновременно? У меня проект MFC на MS Visual 2003. Использует gdi. Хочу перейти на gdi+. Но как-то не хочется все заново переписывать.
« Последнее редактирование: 04-12-2008 12:22 от АлексейК » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 04-12-2008 12:33 » 

скорее всего ничего не мешает ) Ща Джон точно скажет
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #18 : 04-12-2008 14:20 » 

Лёш, инклудируй прицепленный хидер "и не морочь друзьям голову" (с).

А можно на одном CDC рисовать с помощью gdi и gdi+ одновременно?

Что значит одновременно? Чёт тут какое-то непонимание наверное... Всё очень просто. Всё рисуется ТОЛЬКО в GDI.  Я получаю (создаю... не важно) доступ к девайсконтексту усройства вывода (монитор, принтер...), который тоже ОДИН. И начинаю в нём рисовать средствами GDI. Потом в какой-то момент я решаю, что эти средства слишком сложны для  и я создаю "вспомогательный" объект, который в конечном итогде использует те же средства GDI,  из библиотеки gdi+. Инициализирую его ЭТИМ же девайсконтекстом и использую уже более удобные для меня объекты и ф-ции. Вот и всё.

В последнем примере я бы мог например сделать рамочку вокруг картинки таким образом:

      pDC->Rectangle(5,5,15+uiWidth, 15+uiHeight);
      graphics->DrawImage(&image, 10, 10, uiWidth, uiHeight);

Если это для тебя называется одновременно, то ДА - можно. Только соблюдая очерёдность.

Кстати, в отличии от С#, в С++ это "одновременное" использование даёт большое преимущество, например для использования ROP ф-ций. В до-диезе приходится уже "химичить".
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #19 : 04-12-2008 14:30 » 

О! придумал аналогию.

При работе с char[] можно использовать ф-ции strcmp, str*, printf и тд. А можно проинить этим char[] объект CString и делать практически тоже самое, но удобнее.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
АлексейК
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #20 : 04-12-2008 21:12 » 

Большое спасибо за информацию Класс!. Согласен с вами. "Одновременно" не очень удачный термин. Я хотел спросить, возможен ли совместный (или общий) доступ двух объектов к одному и тому же устройству вывода внутри одного потока. Из вашего сообщения понял, что возможен.
Однако, не уверен, что пример со строками аналогичен. CString и char* адресуют разные массивы.
Кроме того, для использования graphics надо вызвать GdiplusStartup и GdiplusShutdown как в следующем примере http://msdn.microsoft.com/en-us/library/ms533895(VS.85).aspx
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 05-12-2008 04:32 » 

качаю вот это
h**p://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm

если не прав - остановите )) Качаться будет ещё долго
Записан

АлексейК
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 05-12-2008 08:27 » 


А чем данное SDK лучше предыдущего? Где-нибудь об этом пишут?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #23 : 05-12-2008 09:20 » 

"данное" и "предыдущее" - это какие ? Я так вообще ещё не пользовался, поэтому не знаю ))
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #24 : 05-12-2008 12:27 » 

Однако, не уверен, что пример со строками аналогичен. CString и char* адресуют разные массивы.

Пример аналогичен только удобстовом получения результата. В данном случае и CDC и Graphic объекты используют свои собственные РАЗНЫЕ ресурсы.

Лёш, похоже, что оно. Я просто ставлю с диска MSDN, поэтому про онлайн ресурсы не в курсе. Но судя по описанию - оно.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #25 : 05-12-2008 19:44 » 

ага, установилось, всё норм ) Пример с картинкой тоже проканал (даже не знал, что у меня есть файл d:\my_photo.jpg Отлично (щютко)

в общем, буду осваивать новую вещь )


ЗЫ а мелкософту за такой инсталлятор надо отрывать ноги и руки и засовывать не поверите, куда.
« Последнее редактирование: 05-12-2008 19:47 от Алексей1153++ » Записан

АлексейК
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #26 : 05-12-2008 20:48 » 


IMHO, для того, чтобы в 6-й студии юзать gdi+ все SDK можно было не качать, а только непосредственно gdi+.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #27 : 05-12-2008 20:59 » 


IMHO, для того, чтобы в 6-й студии юзать gdi+ все SDK можно было не качать, а только непосредственно gdi+.

где ж ты раньше был )) Да в принципе, 354 метра всего
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #28 : 06-12-2008 09:06 » 

Ты студию можешь не инсталить, но SDK иметь обязан!

Это ж альфа и омега. Как вы ваще без неё работаете?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #29 : 06-12-2008 09:50 » 

Это ж альфа и омега. Как вы ваще без неё работаете?
чисто по незнанию Улыбаюсь Вот теперь имеем. Улыбаюсь)
Записан

Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines