Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.68/19: Рейтинг темы: голосов - 19, средняя оценка - 4.68
101 / 38 / 0
Регистрация: 16.09.2014
Сообщений: 426

Пропорциональное увеличение/уменьшение картинки

14.11.2018, 13:55. Показов 3689. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!
Юзер выбирает картинки с помощью стандартного диалогового окна с мультиселектом. Выбранные картинки грузятся в невидимые пикчербоксы (AutoSize=True), юзер же видит их превьюшки (64х64 пикс) на “ленте”. Надо, чтобы при наведении мышки на превьюшку показывалось увеличенное изображение (источник – оригинальный рисунок со скрытого пикчербокса), но с соблюдением следующих условий:
1. Размер увеличенного изображения ограничен MaxHeight и MaxWidth
2. Если оригинальное изображение меньше MaxHeight и MaxWidth, оно выводится в «натуральном» размере без увеличения/уменьшения
3. Если изображение больше одним из измерений или обоими, то оно уменьшается так, чтобы ни одно из измерений не выходило за рамки заданных MaxHeight и MaxWidth

Я как-то вроде сделал это всё процентов на 80 (с использованием BitBlt и StretchBlt), но, во-первых, очень коряво и избыточно-многострочно с кучей Select Case-ов, с определением типа рисунка – квадрат, портрет, ландшафт, а во-вторых и это самое главное – не уверен что логика моего кода учитывает все варианты и не упускает какой нибудь ситуации, когда уменьшили, скажем, Heigt до размера MaxHeight, но ширина всё-таки осталась больше MaxWidth и тому подобное.
Может кто-нибудь подскажет правильную схему, логику этого дела?

Заранее благодарен откликнувшимся
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.11.2018, 13:55
Ответы с готовыми решениями:

Как сделать пропорциональное увеличение формы во весь экран
У меня форма у которой ширина 1000, а высота 2000 и есть картинка с высота 200 ширина 500. И мне надо чтобы эта форма была во весь экран,...

Пропорциональное увеличение и уменьшение элементов на форме
Как сделать пропорциональное увеличение и уменьшение элементов на форме, если потянуть за правый нижний угол формы?

Пропорциональное уменьшение/увеличение фона в зависимости от размера блока
Добрый день! Посоветуйте пожалуйста, как пропорционально уменьшать backround: url(image); И как задать background-size: cover; через...

9
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
14.11.2018, 19:52
Лучший ответ Сообщение было отмечено giaber как решение

Решение

Visual Basic
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
Option Explicit
 
Private WithEvents picCanvas    As PictureBox
 
Private Sub DrawFit( _
            ByVal hdc As Long, _
            ByVal cPic As IPicture, _
            ByVal ldw As Long, _
            ByVal ldh As Long)
    Dim lsw As Long
    Dim lsh As Long
    Dim ldx As Long
    Dim ldy As Long
    Dim lrw As Long
    Dim lrh As Long
    Dim fdt As Single
    
    lsw = CLng(((cPic.Width / 2540) * 1440) / Screen.TwipsPerPixelX)
    lsh = CLng(((cPic.Height / 2540) * 1440) / Screen.TwipsPerPixelY)
    ldx = (ldw - lsw) \ 2
    ldy = (ldh - lsh) \ 2
      
    If ldx < 0 Or ldy < 0 Then
    
        If ldx < ldy Then
            fdt = ldw / lsw: lrw = ldw:  lrh = lsh * fdt
        Else
            fdt = ldh / lsh: lrh = ldh:  lrw = lsw * fdt
        End If
        
        ldx = (ldw - lrw) \ 2
        ldy = (ldh - lrh) \ 2
        
    Else
        lrw = lsw:  lrh = lsh
    End If
 
    cPic.Render hdc, ldx, ldy, lrw, lrh, 0, cPic.Height, cPic.Width, -cPic.Height, ByVal 0&
    
End Sub
 
Private Sub Form_Load()
    
    Set picCanvas = Me.Controls.Add("VB.PictureBox", "picCanvas")
    
    picCanvas.Move 0, 0, Me.ScaleWidth, Me.ScaleHeight
    picCanvas.OLEDropMode = 1
    picCanvas.AutoRedraw = True
    picCanvas.ScaleMode = vbPixels
    picCanvas.Visible = True
    
End Sub
 
Private Sub picCanvas_OLEDragDrop( _
            ByRef Data As DataObject, _
            ByRef Effect As Long, _
            ByRef Button As Integer, _
            ByRef Shift As Integer, _
            ByRef X As Single, _
            ByRef Y As Single)
    Dim vFile   As Variant
    Dim cPic    As StdPicture
    
    On Error GoTo err_handler
    
    For Each vFile In Data.Files
            
        Set cPic = LoadPicture(vFile)
        
        picCanvas.Cls
        
        DrawFit picCanvas.hdc, cPic, picCanvas.ScaleWidth, picCanvas.ScaleHeight
        
        picCanvas.Refresh
        
    Next
    
err_handler:
    
End Sub
2
101 / 38 / 0
Регистрация: 16.09.2014
Сообщений: 426
15.11.2018, 21:32  [ТС]
Уважаемый The Trick!
Как всегда ваш код прекрасен и железно работает. Но, тоже как всегда, я никак не могу его нормально понять. Ну вроде ничего сложного, кажется, что логика понятна, но когда пытаюсь встроить его в свою прогу, заменяя ваши названия lsw, lsh, ldx, ldy и тп на свои, просто используя ваш алгоритм - реально не получается, то никак не могу центрировать, то не садится в MaxH и в MaxW, в общем с утра сижу почти не вставая, но так и не добился результата. Как всегда в чём-то сильно туплю. Стыдно, конечно – красивый, но несложный код и такая тупость с моей стороны….
Вот, хочу попросить – может не затруднитесь и сделаете то же самое в варианте, как бы максимально имитирующем условия моей проги. Там просто 2 пикчербокса: picOrigin и picPreview и зона MaxH и MaxW (для наглядности «очерчена»). Рисунок из picOrigin должен стретчится в picPreview с использованием:
Visual Basic
1
2
3
4
'High quality stretch Blt
Public Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Public Declare Function SetStretchBltMode Lib "gdi32" (ByVal hdc As Long, ByVal hStretchMode As Long) As Long
Public Const STRETCHMODE = vbPaletteModeNone.
Был бы черезвычайно вам благодарен!
Вложения
Тип файла: zip Proportional Stretch.zip (5.95 Мб, 29 просмотров)
0
101 / 38 / 0
Регистрация: 16.09.2014
Сообщений: 426
17.11.2018, 20:45  [ТС]
Всё получилось! Просто один день не подходил к компу, мозговой спазм прошёл и легко так всё пошло, как по маслу!
Ещё раз СПАСИБО за лаконичный код, The Trick!
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
25.09.2023, 18:37
Цитата Сообщение от The trick Посмотреть сообщение
2540) * 1440
Скажи пожалуйста, а что это за фиксированные цифры 2540 и 1440? Ну так, чтоб я понимал код, всё-таки я им пользуюсь. А то наводит на странные мысли...
0
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
25.09.2023, 19:18
HackerVlad, 'это перевод из HIMETRIC в твипы.
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
08.10.2023, 15:33
The trick, для получения размера картинки, кстати, я нашёл другой код, более понятный:

Visual Basic
1
2
    lsw = CLng(ScaleX(cPic.width, vbHimetric, vbPixels))
    lsh = CLng(ScaleY(cPic.height, vbHimetric, vbPixels))
1
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
08.10.2023, 20:51
HackerVlad, этот код можно разместить только в форме (в других модулях нет свойств ScaleX/ScaleY) + он медленнее.
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
10.10.2023, 10:23
Цитата Сообщение от The trick Посмотреть сообщение
DrawFit picCanvas.hdc, cPic, picCanvas.ScaleWidth, picCanvas.ScaleHeight
Кстати, одно маленькое замечание позволю: picCanvas.ScaleWidth в 125% размере экрана будет неправильно определяться. Для других DPI надо писать:

Visual Basic
1
DrawFit Picture1.hDC, cPic, Picture1.Width / Screen.TwipsPerPixelX, Picture1.Height / Screen.TwipsPerPixelY
Добавлено через 1 минуту
Такой код у меня работает правильно, при растягивании пикчебокса.
0
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
10.10.2023, 20:29
Цитата Сообщение от HackerVlad Посмотреть сообщение
Кстати, одно маленькое замечание позволю: picCanvas.ScaleWidth в 125% размере экрана будет неправильно определяться. Для других DPI надо писать:
Это проблема вб. У него значения TwipsPerPixels всегда целочисленные. Поэтому если пишешь DPI-Aware приложение необходимо все размеры задавать в пикселях и масштабировать вручную.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.10.2023, 20:29
Помогаю со студенческими работами здесь

Пропорциональное уменьшение картинки по двум сторонам
Нужно пропорционально уменьшить картинку но так чтобы она была не более 100px по высоте но и не более ширины дива в котором она...

Увеличение и уменьшение картинки
как увеличить и уменьшить картинку через Image при нажатии соответствующей кнопки? Image1-&gt;Height*2 не работает....или я что-то не...

Увеличение и уменьшение картинки
Помогите реализовать на C#: При первом щелчке картинка увеличивалась, а при повторном - уменьшалась? И при этом всегда оставалась на...

Увеличение/уменьшение картинки
Ребята помогите !Срочно нада на завтра исходник програми !Которая *Увеличивает картинку и уменшает ***

Увеличение и уменьшение картинки
Подскажите, пожалуйста! Я в TImage вставила картинку. Мне надо применить к ней zoom (нажимая на определенную область картинки она должна...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
Установка Emscripten SDK (emsdk) и CMake на Windows для сборки C и C++ приложений в WebAssembly (Wasm)
8Observer8 30.01.2026
Чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. Система контроля версиями Git. . .
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru