![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Здравствуйте, делаю лабу, нужно наложить одно изображение на другое, для этого используется Alpha-наложение при помощи API AlphaBlend. Если выбирается jpg, то я преобразую jpg в bmp и пытаюсь наложить. Если оба выбранных изображения bmp, или оба jpg, то всё накладывается отлично, если одно jpg, а другое bmp, то GetLastError с кодом 87(неверно задан параметр). Понятно, что я как-то недопреобразовал jpg, но информации о том, как правильно сделать не нашел.
Может найдется добрый дядя, который мне поможет? Вот код: Код:
procedure TForm1.Button1Click(Sender: TObject); var bmp1, bmp2: TBitMap; jpg1, jpg2: TJpegImage; Blend: TBlendFunction; i, j: integer; s1, s2: string; begin jpg1 := TJpegImage.Create; jpg2 := TJpegImage.Create; bmp1 := TBitMap.Create; bmp2 := TBitMap.Create; try i := pos('.', edit1.Text); j := pos('.', edit2.Text); s1 := Copy(edit1.text, i + 1, 3); s2 := Copy(edit2.text, j + 1, 3); if ((s1 = 'jpg') or (s1 = 'jpeg')) and ((s2 = 'jpg') or (s2 = 'jpeg')) then //если оба jpg begin jpg1:=TJPEGImage.Create; bmp1:=TBitmap.Create; jpg1.CompressionQuality:=100; jpg1.Compress; jpg1.LoadFromFile(Edit1.Text); bmp1.Assign(jpg1); jpg2:=TJPEGImage.Create; bmp2:=TBitmap.Create; jpg2.CompressionQuality:=100; jpg2.Compress; jpg2.LoadFromFile(Edit2.Text); bmp2.Assign(jpg2); end; if ((s1 = 'jpg') or (s1 = 'jpeg')) and (s2 = 'bmp') then //если первый jpg, а второй bmp begin jpg1:=TJPEGImage.Create; bmp1:=TBitmap.Create; jpg1.CompressionQuality:=100; jpg1.Compress; jpg1.LoadFromFile(Edit1.Text); bmp1.Assign(jpg1); end; if ((s2 = 'jpg') or (s2 = 'jpeg')) and (s1 = 'bmp') then //если первый bmp, а второй jpg begin jpg2:=TJPEGImage.Create; bmp2:=TBitmap.Create; jpg2.CompressionQuality:=100; jpg2.Compress; jpg2.LoadFromFile(Edit2.Text); bmp2.Assign(jpg2); end; if (s1 = 'bmp') and (s2 = 'bmp') then //если оба bmp begin bmp1.LoadFromFile(Edit1.Text); bmp2.LoadFromFile(Edit1.Text); end; bmp1.PixelFormat := pf32bit; bmp2.PixelFormat := pf32bit; Blend.BlendOp := AC_SRC_OVER; Blend.BlendFlags := 0; Blend.SourceConstantAlpha := ScrollBar1.Position; Blend.AlphaFormat := AC_SRC_ALPHA; if Windows.AlphaBlend(bmp1.Canvas.Handle, 0, 0, bmp1.Width, bmp1.Height, bmp2.Canvas.Handle, 0, 0, bmp2.Width, bmp2.Height, Blend) then image1.Canvas.Draw(0, 0, bmp1) else ShowMessage(IntToStr(GetLastError)); bmp1.Free; bmp2.Free; except ShowMessage('Не удалось выполнить наложение, проверьте правильность путей' + #10#13 + 'для выбранных изображений'); end; end; |
#2
|
||||
|
||||
![]() Цитата:
![]() Код:
procedure TForm1.Button1Click(Sender: TObject); function GetBitmap(const FileName: string): TBitmap; var ext: string; bmp: TBitmap; jpg: TJPEGImage; begin Result := nil; ext := AnsiLowerCase(ExtractFileExt(FileName)); if ext = '.bmp' then begin bmp := TBitmap.Create; try bmp.LoadFromFile(FileName); Result := bmp; bmp := nil; finally bmp.Free; end; end else if (ext = '.jpg') or (ext = '.jpeg') then begin jpg := TJPEGImage.Create; try jpg.LoadFromFile(FileName); bmp := TBitmap.Create; try bmp.Assign(jpg); Result := bmp; bmp := nil; finally bmp.Free; end; finally jpg.Free; end; end else begin raise Exception.Create('Неизвестное расширение у файла: "' + FileName + '"'); end; end; var bmp1, bmp2: TBitmap; Blend: TBlendFunction; err: DWORD; begin try bmp1 := GetBitmap(Edit1.Text); try bmp2 := GetBitmap(Edit2.Text); try bmp1.PixelFormat := pf32bit; bmp2.PixelFormat := pf32bit; Blend.BlendOp := AC_SRC_OVER; Blend.BlendFlags := 0; Blend.SourceConstantAlpha := ScrollBar1.Position; Blend.AlphaFormat := AC_SRC_ALPHA; if Windows.AlphaBlend(bmp1.Canvas.Handle, 0, 0, bmp1.Width, bmp1.Height, bmp2.Canvas.Handle, 0, 0, bmp2.Width, bmp2.Height, Blend) then begin Image1.Canvas.Draw(0, 0, bmp1); // или так: // Image1.Picture.Assign(bmp1); end else begin err:=GetLastError; MessageDlg('Ошибка №'+IntToStr(err)+': "'+SysErrorMessage(err)+'"', mtError, [mbOK], 0); end; finally bmp2.Free; end; finally bmp1.Free; end; except on E: Exception do begin MessageDlg('Возникло исключение класса "'+E.ClassName+'", с сообщением "'+ E.Message+'"', mtError, [mbOk], 0 ); end; end; end; |
#3
|
|||
|
|||
![]() Спасибо, конечно, огромное, за переделку, а не могли бы Вы мне сказать каким нибудь русским предложением, в чём была моя ошибка? Так было бы быстрее. Если не учитывать все мелкие различия, то бросается в глаза следующее, у Вас в функции преобразования нет сжатия.
Убрал сжатие не помогло, та же ошибка. Если есть еще какая-то принципиальная разница между процедурами я её не заметил. Последний раз редактировалось Fredwriter, 17.09.2012 в 19:03. |
#4
|
|||
|
|||
![]() Нашел ошибку, оказалось, я когда у меня разные форматы, загружал только jpg, а bmp забыл. Банальная невнимательность.
|
#6
|
|||
|
|||
![]() |
#7
|
|||||||
|
|||||||
![]() Цитата:
Вот в этом коде: Код:
jpg1:=TJPEGImage.Create; bmp1:=TBitmap.Create; jpg1.CompressionQuality:=100; jpg1.Compress; Цитата:
Но самое главное, что сам принцип неправильный (поэтому я и переписал исходник вместо того, чтобы просто внести мелкие исправления): не нужно перечислять все возможные комбинации форматов входных картинок, типа: Цитата:
Цитата:
Вместо этого достаточно просто описать одну функцию, которая будет преобразовывать любую картинку известного ей формата в Bitmap. Тогда с помощью этой функции преобразуем две нужные картинки в Bitmap'ы, которые и отдаём процедуре AlphaBlend (которая только с Bitmap'ами собственно говоря и умеет работать). Цитата:
Цитата:
Чтобы не растягивалось нужно указывать оба прямоугольника одинаковыми и равными размерам источникового прямоугольника: Код:
// Т.е. не так: if Windows.AlphaBlend(bmp1.Canvas.Handle, 0, 0, bmp1.Width, bmp1.Height, bmp2.Canvas.Handle, 0, 0, bmp2.Width, bmp2.Height, Blend) then // а так: if Windows.AlphaBlend(bmp1.Canvas.Handle, 0, 0, bmp2.Width, bmp2.Height, bmp2.Canvas.Handle, 0, 0, bmp2.Width, bmp2.Height, Blend) then Цитата:
![]() |
#8
|
|||
|
|||
![]() Спасибо, помогло. Теперь еще один момент, я в программе, сначала двигаю мышкой источник по целевому изображению, он у меня меньше целевого, а затем, мне нужно наложить его на целевое изображение там куда я его передвинул, а оно, так как верхние углы у обоих изображений 0, 0, понятно, всегда в правом верхнем углу накладывается. Если пытаться поменять эти нули на точку, в которой находится верхний левый угол источника, то выходит ошибка 87.
Последний раз редактировалось Fredwriter, 18.09.2012 в 08:56. |
#9
|
||||
|
||||
![]() Цитата:
Например если X и Y это координаты левого верхнего угла где нужно нарисовать источник, то рисовать нужно так: Код:
if Windows.AlphaBlend(bmp1.Canvas.Handle, X, Y, bmp2.Width + X, bmp2.Height + Y, bmp2.Canvas.Handle, 0, 0, bmp2.Width, bmp2.Height, Blend) then |
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение: | ||
Fredwriter (18.09.2012)
|
#10
|
|||
|
|||
![]() Понятно, спасибо.
|