На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> BMP to RTF , WinAPI
    Пишу самодельный эл.управления типа RichTextBox для вывода результатов программы. RichTextBox не устраивает, потому что нужны разделения на страницы и миниатюры страниц как в pdf- или djvu- просмотрщиках.
    Появилась задача вставить картинки, кроме текста. Делаю на чистом WinAPI без MFC и др. Само рисование не вызывает вопросов. Проблема в следующем, чтобы выделить и скопировать, а потом вставить текст с картинками в Word, нужно перевести эти текст и картинки в формат RTF. Интересует перевод именно рисунков в RTF.

    По теме найдено
    1) из Delphi Russian Knowledge Base 3, благодоря проделанной работе Vit-a
    Скрытый текст

    ExpandedWrap disabled
      function BitmapToRTF(pict: TBitmap): string;
       
      var
       
      bi, bb, rtf: string;
       
      bis, bbs: Cardinal;
       
      achar: ShortString;
       
      hexpict: string;
       
      I: Integer;
       
      begin
       
      GetDIBSizes(pict.Handle, bis, bbs);
       
      SetLength(bi, bis);
       
      SetLength(bb, bbs);
       
      GetDIB(pict.Handle, pict.Palette, PChar(bi)^, PChar(bb)^);
       
      rtf := '{\rtf1 {\pict\dibitmap0 ';
       
      SetLength(hexpict, (Length(bb) + Length(bi)) * 2);
       
      I := 2;
       
      for bis := 1 to Length(bi) do
       
      begin
       
         achar := IntToHex(Integer(bi[bis]), 2);
       
         hexpict[I - 1] := achar[1];
       
         hexpict[I] := achar[2];
       
         Inc(I, 2);
       
      end;
       
      for bbs := 1 to Length(bb) do
       
      begin
       
         achar := IntToHex(Integer(bb[bbs]), 2);
       
         hexpict[I - 1] := achar[1];
       
         hexpict[I] := achar[2];
       
         Inc(I, 2);
       
      end;
       
      rtf := rtf + hexpict + ' }}';
       
      Result := rtf;
       
      end;

    Но для меня здесь проблема в функциях из VCL (GetDIBSizes, GetDIB) их переводе на Си.

    2) Нашел по адресу microsoft.public.pocketpc.developer.narkive.com
    Скрытый текст

    ExpandedWrap disabled
      PBITMAPINFO pbmi = NULL;
      WORD cClrBits = 1;
      int nColors = 2;
      RGBQUAD Colors2[] =
      {
      {0x00, 0x00, 0x00, 0x00},
      {0xFF, 0xFF, 0xFF, 0x00}
      };
       
      int nBytesPerLine = ((nWidth * cClrBits + 31)&(~31)) / 8;
      DWORD dwBitmapInfoSize = sizeof(BITMAPINFOHEADER) + nColors * sizeof
      (RGBQUAD);
      DWORD dwFileHeaderSize = dwBitmapInfoSize + sizeof(BITMAPFILEHEADER);
      HBITMAP hBmp;
      LPVOID ppvBits;
      BYTE *lpBits, *lpBuf = new BYTE[dwBitmapInfoSize + 1];
      BITMAPINFO* lpbi = (BITMAPINFO*) lpBuf;
      BITMAPFILEHEADER bmpfhdr;
      BITMAPINFOHEADER& bih = lpbi->bmiHeader;
       
      // Initialize the fields in the BITMAPINFO structure.
      memset(&bih, 0, sizeof(BITMAPINFOHEADER));
      bih.biSize = sizeof(BITMAPINFOHEADER);
      bih.biWidth = nWidth;
      bih.biHeight = nHeight;
      bih.biPlanes = 1;
      bih.biBitCount = 1;
      bih.biCompression = BI_RGB;
      bih.biSizeImage = 0;
       
      RGBQUAD* pColors = &Colors2[0];
      memcpy(&lpbi->bmiColors[0], &pColors[0], sizeof(RGBQUAD));
      memcpy(&lpbi->bmiColors[1], &pColors[1], sizeof(RGBQUAD));
       
      bmpfhdr.bfType = 0x4d42; //'BM' file type
      bmpfhdr.bfSize = dwFileHeaderSize + (nBytesPerLine * nHeight);
      bmpfhdr.bfReserved1 = 0;
      bmpfhdr.bfReserved2 = 0;
      bmpfhdr.bfOffBits = dwFileHeaderSize;
       
      // Then create our DIBSection using the structure manually created
      from above...
      HBITMAP hPictureBMP = CreateDIBSection(pictureDC, lpbi,
      DIB_RGB_COLORS, &ppvBits, NULL, 0);
      lpBits = (BYTE*)ppvBits;
      HDC hMemDC = CreateCompatibleDC(pictureDC);
       
      hBmp = (HBITMAP) SelectObject(hMemDC, hPictureBMP);
      BitBlt(hMemDC,0,0,nWidth,nHeight,pictureDC,0,0,SRCCOPY);
      SelectObject(hMemDC, hBmp);
      DeleteObject(hPictureBMP);
       
      DWORD dwNumBytes;
       
      if (ppvBits)
      {
      char szBuffer[MAX_BUFFER];
       
      // pichgoal = 1440 / DPI = 1440 / 96 = 15
      int rtfHeaderSize = sprintf(szBuffer,"{\\pict\\dibitmap0\
      \wbmbitspixel%u\\wbmplanes%u\\wbmwidthbytes%u\\picw%u\\pich%u\\picwgoal
      %u\\pichgoal%u\\picscalex100\\picscaley100 ", bih.biBitCount,
      bih.biPlanes, nBytesPerLine, nWidth, nHeight, nWidth*16, nHeight*16);
      {
      int offset;
      for (offset=0; offset < (int)dwBitmapInfoSize; offset++)
      sprintf(szBuffer+rtfHeaderSize+offset*2,"%02X",lpBuf[offset]);
      for (offset=0; offset<nBytesPerLine * nHeight; ++offset)
      sprintf(szBuffer+rtfHeaderSize+(dwBitmapInfoSize+offset)
      *2,"%02X",lpBits[offset]);
      }
      szBuffer[rtfHeaderSize + (dwBitmapInfoSize + nBytesPerLine *
      nHeight) * 2] = '}';
      szBuffer[rtfHeaderSize + (dwBitmapInfoSize + nBytesPerLine *
      nHeight) * 2 + 1] = 0;
       
      // Insert bitmap into document (there is enough rooom!!)
      memmove(documentSignature + strlen(szBuffer), documentSignature,
      strlen(documentSignature) + 1);
      memcpy (documentSignature, szBuffer, strlen(szBuffer));
      }
      delete[] lpBuf;
      DeleteObject(hBmp);
      DeleteDC(hMemDC);


    Этот код взял за основу, переделываю под свою задачу.
    ExpandedWrap disabled
      void ReportPicturesToRTF()
      {
          int i;
          int w, h, ncolors, nbytesperline, rtfheadersize;
          char buffer[256];
          HDC picturedc, hmemdc;
          HBITMAP hbmp, hpicturebmp;
          PBITMAPINFO pbmi;
          LPVOID ppvbits;
          BITMAPFILEHEADER bmpfhdr;
          WORD clrbits;
          DWORD dwbitmapinfosize, dwfileheadersize;
          BYTE *lpbits, *lpbuf;
          BITMAPINFO *lpbi;
          RGBQUAD* pcolors;
          RGBQUAD colors2[] =
          {
              {0x00, 0x00, 0x00, 0x00},
              {0xFF, 0xFF, 0xFF, 0x00}
          };
          picturedc = GetDC(e::reporthwnd[3]); // <--- здесь я беру окно со свои рисунком
          pbmi = NULL;
          clrbits = 1;
          ncolors = 2;
          w = 100;
          h = 20;
          nbytesperline = ((w * clrbits + 31) & (~31)) / 8;
          dwbitmapinfosize = sizeof(BITMAPINFOHEADER) + ncolors * sizeof(RGBQUAD);
          dwfileheadersize = dwbitmapinfosize + sizeof(BITMAPFILEHEADER);
          lpbuf = new BYTE[dwbitmapinfosize + 1];
          lpbi = (BITMAPINFO*) lpbuf;
          BITMAPINFOHEADER& bih = lpbi->bmiHeader;
          memset(&bih, 0, sizeof(BITMAPINFOHEADER));
          bih.biSize = sizeof(BITMAPINFOHEADER);
          bih.biWidth = w;
          bih.biHeight = h;
          bih.biPlanes = 1;
          bih.biBitCount = 1;
          bih.biCompression = BI_RGB;
          bih.biSizeImage = 0;
          pcolors = &colors2[0];
          memcpy(&lpbi->bmiColors[0], &pcolors[0], sizeof(RGBQUAD));
          memcpy(&lpbi->bmiColors[1], &pcolors[1], sizeof(RGBQUAD));
          bmpfhdr.bfType = 0x4d42;
          bmpfhdr.bfSize = dwfileheadersize + (nbytesperline * h);
          bmpfhdr.bfReserved1 = 0;
          bmpfhdr.bfReserved2 = 0;
          bmpfhdr.bfOffBits = dwfileheadersize;
          hpicturebmp = CreateDIBSection(picturedc, lpbi, DIB_RGB_COLORS, &ppvbits, NULL, 0);
          lpbits = (BYTE*)ppvbits;
          hmemdc = CreateCompatibleDC(picturedc);
          hbmp = (HBITMAP) SelectObject(hmemdc, hpicturebmp);
          BitBlt(hmemdc, 0, 0, w, h, picturedc, 0, 0, SRCCOPY);
          SelectObject(hmemdc, hbmp);
          if (ppvbits)
          {
              rtfheadersize = sprintf(buffer,"{\\pict\\dibitmap0\\wbmbitspixel%u\\wbmplanes%u\\wbmwidthbytes%u\\picw%u\\pich%u\\picwgoal%u\\pichgoal%u\\picscalex100\\picscaley100 ", bih.biBitCount,bih.biPlanes, nbytesperline, w, h, w*16, h*16);
              {
                  for (i=0; i<((int)dwbitmapinfosize); i++)
                  {
                      sprintf(buffer + rtfheadersize+i * 2, "%02X", lpbuf[i]);
                  }
                  for (i=0; i<(nbytesperline*h); ++i)
                  {
                      sprintf(buffer + rtfheadersize + (dwbitmapinfosize + i) * 2, "%02X", lpbits[i]);
                  }
              }
              buffer[rtfheadersize + (dwbitmapinfosize + nbytesperline * h) * 2] = '}';
              buffer[rtfheadersize + (dwbitmapinfosize + nbytesperline * h) * 2 + 1] = 0;
       
              // Insert bitmap into document (there is enough rooom!!)
              //memmove(documentSignature + strlen(buffer), documentSignature, strlen(documentSignature) + 1);
              //memcpy (documentSignature, buffer, strlen(buffer));
          }
          delete[] lpbuf;
          DeleteObject(hpicturebmp);
          DeleteObject(hbmp);
          DeleteDC(hmemdc);
      }

    Вопросы:
    1. Здесь, как я понял, для 2-х цветных (черно-белых) BMP. А как быть с большим количеством цветности ? Хотелось бы как минимум 256.
    2. Есть ли уже готовые решения для такой задачи ?
    Сообщение отредактировано: Betelgeuse -
      Цитата Betelgeuse @
      2. Есть ли уже готовые решения для такой задачи ?

      Не подобное ли ты ищешь?
        Цитата B.V. @
        Не подобное ли ты ищешь?

        Не похоже,
        Там судя по названиям OLE технология используется. И нигде в HEX-значения перевода нет

        А мне нужно
        1) мой hDC перегнать в HBITMAP
        2) из HBITMAP выудить всю эту информацию (заголовки, размеры, цвета)
        3) с учетом этой информации записать в СТРОКУ область данных рисунка HEX-значения
        4) Потом эту СТРОКУ можно будет скопировать в буфер обмена.

        Застрял на изучении формата BMP (такая муть!)
        Сейчас сочиняю на Си функцию из VCL которая там имеет название GetDIBSizes()...

        PS думал за день справлюсь - ошибался ))
          B.V.Спасибо за наводку на сайт, www.codeproject.com
          Я про него как-то забыл )) надо там внимательнее поискать.
          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,0367 ]   [ 16 queries used ]   [ Generated: 27.04.24, 09:33 GMT ]