![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | 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
|
|||
|
|||
|
Понятно, спасибо.
|