Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.90/30: Рейтинг темы: голосов - 30, средняя оценка - 4.90
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585

Качественно растянуть изображение

02.02.2014, 16:54. Показов 7493. Ответов 36
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Необходимо загрузить из файла изображение и вывести его на область формы, соответственно, сжав или растянув.
Самое простое, что пришло в голову, это метод StreachDraw:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
TJPEGImage *tJpg;
    String FileName = ExtractFilePath(Application->ExeName) + "01.jpg";
    TRect tRect;
 
    tRect.Left = 0; tRect.Right  = Width;
    tRect.Top  = 0; tRect.Bottom = Height;
 
    if (!FileExists(FileName))
    {
        ShowMessage(FileName + " не существует.");
        return;
    }
 
    tJpg = new TJPEGImage;
    tJpg->LoadFromFile(FileName);
 
    Canvas->StretchDraw(tRect, tJpg);
 
    delete tJpg;
Проблема в том, что этот метод работает ужасно: что растянутое, что сжатое изображение получается все в "квадратиках" и смотрится не приемлемо. Любые графические редакторы растягивают или сжимают изображения более качественно.
Вопрос: какие есть средства у CBuilder или Windows API для качественно изменения размеров изображения?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.02.2014, 16:54
Ответы с готовыми решениями:

растянуть изображение
здравствуйте, получил задание создать сайт на любую тему. как тема выбралась антология фильмов "star wars". Но столкнулся с...

CSS Растянуть изображение
Здравствуйте, у меня такая проблема... У меня сайт http://asv-service.somee.com/ Там есть фоновая картинка... ее нужно растянуть ...

Растянуть изображение в канвас
Нужно чтобы изображение изменялось пропорционально изменению окна. Растягиваешь окно - растягивается изображение. Begin With...

36
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
03.02.2014, 19:59
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от BRcr Посмотреть сообщение
FireMonkey не использует GDI, это вообще одна из причин ее появления в составе RAD Studio: качество + скорость получше.
А я и не говорил про FMX, я говорил про VCL:
Цитата Сообщение от Я
мне просто странно по тому как VCL рисуется тем же простым GDI.
Уточню: меня удивляет почему VCL не использует SetStretchBltMode() если она дает лучший результат.

Что же, в любом случае в своих приложения придется абстрагироваться и отходить от VCL.Canvas так как он к примеру не поддерживает "сглаживание" линий.

0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
03.02.2014, 20:04
Выходит, я не так понял. Все же писать просто и понятно желательно, однако.
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
03.02.2014, 20:07
Цитата Сообщение от Avazart Посмотреть сообщение
меня удивляет почему VCL не использует SetStretchBltMode() если она дает лучший результат
гадая на хрустальном шаре предположу "потому что она дает не такой уж и результат роняя при этом ресурсы"
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
03.02.2014, 20:11
Цитата Сообщение от vxg Посмотреть сообщение
гадая на хрустальном шаре предположу "потому что она дает не такой уж и результат роняя при этом ресурсы"
В смысле при работе именно с данными jpeg ?
Ведь SetStretchBltMode() это ф-ция относящаяся к GDI (не GDI+), как бы не должно быть такой проблемы.
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
03.02.2014, 20:15
Цитата Сообщение от Avazart Посмотреть сообщение
В смысле
в смысле что я вообще не вижу как это она должна работать. в свое время экспериментировал с Stretch функциями и получал унылое г ничем не лучшее метода "ближайшая точка". причем непредсказуемое. видимо я так и не смог понять шекспировский язык документации именно к этой функции.
0
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
03.02.2014, 20:25  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Уточню: меня удивляет почему VCL не использует SetStretchBltMode() если она дает лучший результат.
Действительно странно, что для того же TImage сделали метод StretchDraw, но не сделали свойство StretchMode...
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
03.02.2014, 20:26
Ну так вроде "роняют", судя по описанию, все кроме HALFTONE которая делает аппроксимацию, в место простого "выкидывания"

HALFTONEMaps pixels from the source rectangle into blocks of pixels in the destination rectangle. The average color over the destination block of pixels approximates the color of the source pixels.After setting the HALFTONE stretching mode, an application must call the SetBrushOrgEx function to set the brush origin. If it fails to do so, brush misalignment occurs.
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
03.02.2014, 20:31
Цитата Сообщение от Avazart Посмотреть сообщение
судя по описанию
прошу меня простить за вольный текст. под "роняют" я имел ввиду "загружают процессор, отнимают ресурсы, жрут их несообразно получаемой выгоде". что касается аппроксимации, то вопрос вопросов - а как именно оно делает аппроксимацию?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
03.02.2014, 20:55
Хм вроде как VCL использует туже SetStretchBltMode()

Кликните здесь для просмотра всего текста
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
procedure TCanvas.StretchDraw(const Rect: TRect; Graphic: TGraphic);
begin
  if Graphic <> nil then
  begin
    Changing;
    RequiredState(csAllValid);
    Graphic.Draw(Self, Rect);
    Changed;
  end;
end;
 
procedure TJPEGImage.Draw(ACanvas: TCanvas; const Rect: TRect);
begin
  ACanvas.StretchDraw(Rect, Bitmap);
end;
 
procedure TBitmap.Draw(ACanvas: TCanvas; const Rect: TRect);
var
  OldPalette: HPalette;
  RestorePalette: Boolean;
  DoHalftone: Boolean;
  Pt: TPoint;
  BPP: Integer;
  MaskDC: HDC;
  Save: THandle;
  BF: TBlendFunction;
begin
  with Rect, FImage do
  begin
    ACanvas.RequiredState(csAllValid);
    PaletteNeeded;
    OldPalette := 0;
    RestorePalette := False;
 
    if FPalette <> 0 then
    begin
      OldPalette := SelectPalette(ACanvas.FHandle, FPalette, True);
      RealizePalette(ACanvas.FHandle);
      RestorePalette := True;
    end;
 
    BPP := GetDeviceCaps(ACanvas.FHandle, BITSPIXEL) *
      GetDeviceCaps(ACanvas.FHandle, PLANES);
    DoHalftone := (BPP <= 8) and (BPP < (FDIB.dsBm.bmBitsPixel * FDIB.dsBm.bmPlanes));
    if DoHalftone then
    begin
      GetBrushOrgEx(ACanvas.FHandle, pt);
      SetStretchBltMode(ACanvas.FHandle, HALFTONE);
      SetBrushOrgEx(ACanvas.FHandle, pt.x, pt.y, {$IFNDEF CLR}@{$ENDIF}pt);
    end
    else
      if not Monochrome then
        SetStretchBltMode(ACanvas.Handle, STRETCH_DELETESCANS);
    try
      { Call MaskHandleNeeded prior to creating the canvas handle since
        it causes FreeContext to be called. }
      if Transparent then MaskHandleNeeded;
      Canvas.RequiredState(csAllValid);
      if Transparent then
      begin
        Save := 0;
        MaskDC := 0;
        try
          MaskDC := GDICheck(CreateCompatibleDC(0));
          Save := SelectObject(MaskDC, FMaskHandle);
          TransparentStretchBlt(ACanvas.FHandle, Left, Top, Right - Left,
            Bottom - Top, Canvas.FHandle, 0, 0, FDIB.dsbm.bmWidth,
            FDIB.dsbm.bmHeight, MaskDC, 0, 0);
        finally
          if Save <> 0 then SelectObject(MaskDC, Save);
          if MaskDC <> 0 then DeleteDC(MaskDC);
        end;
      end
      else if SupportsPartialTransparency then
      begin
        //We have a 32 bit bitmap with alpha, render with AlphaBlend
        BF.BlendOp := AC_SRC_OVER;
        BF.BlendFlags := 0;
        BF.SourceConstantAlpha := 255;
        BF.AlphaFormat := AC_SRC_ALPHA;
 
        Winapi.Windows.AlphaBlend(ACanvas.Handle, Left, Top, Right - Left, Bottom - Top,
          Canvas.FHandle, 0, 0, FDIB.dsbm.bmWidth, FDIB.dsbm.bmHeight, BF);
      end
      else
        StretchBlt(ACanvas.FHandle, Left, Top, Right - Left, Bottom - Top,
          Canvas.FHandle, 0, 0, FDIB.dsbm.bmWidth,
          FDIB.dsbm.bmHeight, ACanvas.CopyMode);
    finally
      if RestorePalette then
        SelectPalette(ACanvas.FHandle, OldPalette, True);
    end;
  end;
end;


Добавлено через 11 минут
Может просто не всегда проходит условие:
Delphi
1
2
3
4
5
6
7
DoHalftone := (BPP <= 8) and (BPP < (FDIB.dsBm.bmBitsPixel * FDIB.dsBm.bmPlanes));
    if DoHalftone then
    begin
      GetBrushOrgEx(ACanvas.FHandle, pt);
      SetStretchBltMode(ACanvas.FHandle, HALFTONE);
      SetBrushOrgEx(ACanvas.FHandle, pt.x, pt.y, {$IFNDEF CLR}@{$ENDIF}pt);
    end
0
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
03.02.2014, 23:00  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Может просто не всегда проходит условие
Скорее, оно всегда не проходит...
Delphi
1
SetBrushOrgEx(ACanvas.FHandle, pt.x, pt.y, {$IFNDEF CLR}@{$ENDIF}pt);
Вы не в курсе, что такое здесь CLR? Что все-таки передается? (Я не силен в Паскале) Указатель на TPoint? Почему бы просто не передать nil (NULL)?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
03.02.2014, 23:05
Цитата Сообщение от znseday Посмотреть сообщение
Вы не в курсе, что такое здесь CLR? Что все-таки передается? (Я не силен в Паскале) Указатель на TPoint? Почему бы просто не передать nil (NULL)?
Delphi
1
{$IFNDEF CLR}@{$ENDIF}
- макрос условной компиляции для компиляции в среде CLR вероятно.

Добавлено через 2 минуты
http://msdn.microsoft.com/en-u... 85%29.aspx
0
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
04.02.2014, 00:42  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
Я там уже был, если Вы про
lppt [out]
A pointer to a POINT structure that receives the previous brush origin.
This parameter can be NULL if the previous brush origin is not required.
Просто не понятно, зачем передают этот параметр в
Delphi
1
SetBrushOrgEx(ACanvas.FHandle, pt.x, pt.y, {$IFNDEF CLR}@{$ENDIF}pt);
, когда он уже получен двумя строчками выше в
Delphi
1
GetBrushOrgEx(ACanvas.FHandle, pt);
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
04.02.2014, 00:46
C++
1
_Out_  LPPOINT lppt
Это out-параметр, ф-ция может изменять его.
0
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
04.02.2014, 14:38  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Это out-параметр, ф-ция может изменять его.
Естественно может, она же туда записывает старое значение. Или я не прав?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
04.02.2014, 16:21
Цитата Сообщение от znseday Посмотреть сообщение
Естественно может, она же туда записывает старое значение. Или я не прав?
Новое значение.
0
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
04.02.2014, 17:16  [ТС]
Я не очень разбираюсь в больших предложениях на английском, но:
lppt [out]
A pointer to a POINT structure that receives the previous brush origin.
This parameter can be NULL if the previous brush origin is not required.
разве речь не о старом, предыдущем значении?
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
04.02.2014, 18:21
Да старое значение туда пишется, старое.
Команды препроцессора вообще закомментированы. Однако в делфях не силен и работа этих строчек мне понятна не до конца.
Delphi
1
2
3
4
5
6
7
DoHalftone := (BPP <= 8) and (BPP < (FDIB.dsBm.bmBitsPixel * FDIB.dsBm.bmPlanes));
    if DoHalftone then
    begin
      GetBrushOrgEx(ACanvas.FHandle, pt); // Получаем координаты в pt 
      SetStretchBltMode(ACanvas.FHandle, HALFTONE); // ставим режим аппроксимации, при этом, видимо сбиваются координаты источника кисти 
      SetBrushOrgEx(ACanvas.FHandle, pt.x, pt.y, {$IFNDEF CLR}@{$ENDIF}pt); // восстанавливаем запомненные координаты, а после этого запоминаем в pt те координаты, которые получились после отработки функции SetStretchBltMode. Зачем - не знаю. 
    end
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.02.2014, 18:21

Растянуть изображение на весь экран
1) Как в проект загрузить изображение? 2) Как весь фон заполнить 1 картинкой и по верх него работать? Т.е растянуть ее на весь экран.

Растянуть или сжать изображение
Как можно растянуть или сжать изображение, используя EMGU CV? То есть, например, у меня есть изображение 100*200. нужно, не сохраняя...

Растянуть изображение на размер экрана
Есть DIV и CSS: &lt;div id=&quot;main-hero&quot; class=&quot;block-home background-cover&quot;&gt; &lt;/div&gt; .block-home { background:...

Растянуть фоновое изображение на весь экран
сам скрипт находится тут: https://script.google.com/macros/s/AKfycbwj7pG7cMoYUanrC31ktOOlNRBZFnrnFBQqEtecFTqmzN7g9iHD/exec и как...

Как растянуть вот так изображение?
Как растянуть вот так изображение? и разместит так текст? body{ background-image: url(../img/head.png); background-repeat:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации: 1. Вернуть возможность использования знаков | 1 l I;. . .
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
Генератор паролей (вариант №2)
Maks 30.10.2026
Обновленная версия ранее созданной обработки. Добавлены следующие реквизиты типа Булево: - Буквы; - Цифры; - Символы. Изменена логика команды "Сгенерировать" и процедуры "ПриОткрытии":. . .
Генератор паролей (вариант №1)
Maks 29.10.2026
Реализация из решения ниже выполнена исключительно по моей инициативе, дабы облегчить себе работу в создании паролей для администрируемых мною сервисов и пользователей. Самым главным критерием для. . .
Установка ChatGPT (Codex) на Windows без использования Microsoft Store
Fabien159 28.10.2026
Здравствуйте всем читающим! Опишу процесс установки ChatGPT (Codex) на Windows, если по каким-то причинам у вас не получается устанавить его через Microsoft Store. И так: 1. Скачиваем с. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru