Я решил записать себе на будущее мои мучения по нормальному уменьшению картинки программно.
В гугле нашлось множество разных способов. Перепробовал кучу, убил немеряно времени. Стандартный способ заключается в использовании StretchDraw.
Это что-то типа такого:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
var jpgImage:TJPEGImage; BitMap:tbitmap; ...... jpgImage.LoadFromFile(filenamein); jpgImage.DIBNeeded; BitMap.Assign(jpgImage); BitMap.Canvas.StretchDraw(Bounds(0,0,100,100),BitMap); jpgImage.Assign(BitMap); jpgImage.CompressionQuality:=90; jpgImage.Compress; jpgImage.SaveToFile(filenameout); |
Качество на выходе, в основном, отвратное. Годится, чтобы создавать на лету картинки, просто посмотреть что имеется, но использовать их просто некрасиво.
С GDI+ подружиться нормально не удалось. В паре программ работало у меня что-то типа такого:
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 |
var fotka: TGPImage; ...... graphicsGDIPlus := TGPGraphics.Create(PaintBox1.Canvas.Handle); fotka:= TGPImage.Create(filein); w1:=fotka.GetWidth; h1:=fotka.GetHeight; w2:=PaintBox1.Width; h2:=PaintBox1.Height; if (w2/w1 < h2)then h2:=round(h1/(w1/w2)) else w2:=round(w1/(h1/h2)); graphicsGDIPlus.DrawImage(fotka, 0, 0,w2, h2); fotka.Free; graphicsGDIPlus.Free; |
Но тут что-то погряз я в коде, заглючило, разозлился и решил раз и навсегда найти решение, которое буду использовать везде. Поиски привели меня к мега-библиотеке Graphics32. Так же под руку попался юнит janFX — прекрасный простой в использовании модуль.
Про janFX я тут записывать не буду, а вот по Graphics32 нужно сделать памятку. Дело в том, что приложенные к библиотеке примеры сделаны так, что просто мозги вывихнешь, пытаясь разобраться. И по интернету я не нашёл ни одного человеческого примера. После нескольких проб получается следующее: нужно сделать два битмапа обязательно(как в первом примере не получится одним битмапом сам в себя), нужно создать ресамплер, перерисовать из одного битмапа в другой, указав уменьшение. Если что-то забыть или сделать не так, то на выходе будет всем известная картина Малевича.
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 |
a,s: TBitmap32; r:TDraftResampler; //Вариантов ресамплинга несколько, можно выбрать какой подходит лучше begin try a:=TBitmap32.Create; s:=TBitmap32.Create; a.LoadFromFile(filename); r:=TDraftResampler.Create; a.Resampler:=r; s.SetSize(640,480); s.Draw(bounds(0,0,640,480),bounds(0,0,a.Width,a.Height),a); s.SaveToFile('a.jpg'); finally //r.Free; — почему-то ругается, если не закомментировано. Возможно, освобождает сама a.Free; s.Free; end; |
ЗЫ
Небольшое дополнение в статью. Сейчас я перешёл на ImageEn. Пока экспериментирую… Потом опишу результаты