Перейти к содержанию
Fire Monkey от А до Я
  • 0

Наложение картинки на фото


Kitty

Вопрос

Приложение делает фотографию и эта фотография попадает в TImage. Потом этой фотографией можно поделиться в соц.сетях.

Можно ли сразу после получения снимка, на фотографию наложить изображение  (маленький логотип) чтобы фотография получилась с наложенным на нее изображением в углу?

Спасибо.

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

В VCL проекте код ниже накладывает логотип на фотографию в правый верхний угол:

//В Image1 загружена основная фотография
//В Image2 загружен png логотип

//щелчок по кнопке
void __fastcall TForm1::Button1Click(TObject *Sender)
{

	TRectF SrcRect(0,0,Image2->Width, Image2->Height);
	// Ищем коэффициенты мастаба картинки по ширине и высоте
	double kWidth = Image1->MultiResBitmap[0].Width / Image1->Width;
	double kHeight = Image1->MultiResBitmap[0].Height / Image1->Height;
	double Koef = Max(kWidth,kHeight) / 2; // выбираем максимальный коеффициент и делим на 2
	double TopLeft = Image1->MultiResBitmap[0].Width - Image2->Width * Koef;
	TRectF DstRect(TopLeft,20,TopLeft + Image2->Width * Koef - 20, Image2->Height * Koef);

	Image1->Bitmap->Canvas->BeginScene();
	Image1->Bitmap->Canvas->DrawBitmap(Image2->Bitmap, SrcRect, DstRect, 1);
	Image1->Bitmap->Canvas->EndScene();

}

Я хочу наложить логотип в мобильном приложении на фотографию сразу после снимка:

void __fastcall TFormCamera::TakePhotoFromCameraAction1DidFinishTaking(TBitmap *Image)
{
 Image1->Bitmap->Assign(Image);

 if(Image1->Bitmap->IsEmpty())
	return;

  ShowMessage(L"Мы здесь");

	//логотип на фото
	TRectF SrcRect(0,0,Form1->Image2->Width, Form1->Image2->Height);
	// Ищем коэффициенты мастаба картинки по ширине и высоте
	double kWidth = Image1->MultiResBitmap[0].Width / Image1->Width;
	double kHeight = Image1->MultiResBitmap[0].Height / Image1->Height;
	double Koef = Max(kWidth,kHeight) / 2; // выбираем максимальный коеффициент и делим на 2
	double TopLeft = Image1->MultiResBitmap[0].Width - Form1->Image2->Width * Koef;
	TRectF DstRect(TopLeft,20,TopLeft + Form1->Image2->Width * Koef - 20,
										Form1->Image2->Height * Koef);

	Image1->Bitmap->Canvas->BeginScene();
	Image1->Bitmap->Canvas->DrawBitmap(Form1->Image2->Bitmap, SrcRect, DstRect, 1);
	Image1->Bitmap->Canvas->EndScene();

}

Однако логотипа на фото не получаю.

Как наложить логотип на фото сразу после сделанного снимка в мобильном приложении?

Спасибо.

Ссылка на комментарий
  • 0
  • Модераторы
procedure TForm5.TakePhotoFromCameraAction1DidFinishTaking(Image: TBitmap);
var
  aBitmap: TBitmap;
  aRectF: TRectF;
begin
  aBitmap := TBitmap.Create;
  aBitmap.SetSize(Image.Width, Image.Height);
  aBitmap.CopyFromBitmap(Image);

  aBitmap.Canvas.BeginScene;
  aRectF := RectF(aBitmap.Width - Image2.Bitmap.Width, aBitmap.Height - Image2.Bitmap.Height, aBitmap.Width,
    aBitmap.Height);
  aBitmap.Canvas.DrawBitmap(Image2.Bitmap, Image2.Bitmap.BoundsF, aRectF, 1, true);
  aBitmap.Canvas.EndScene;

  Image1.Bitmap.Assign(aBitmap);
  aBitmap.Free;
end;

Kitty

void __fastcall TFormCamera::TakePhotoFromCameraAction1DidFinishTaking(TBitmap *Image)

{
 //умный указатель чтобы не использовать delete
 std::unique_ptr<TBitmap> aBitmap(new TBitmap());
 TRectF aRectF;

 aBitmap->SetSize(Image->Width, Image->Height);
 aBitmap->CopyFromBitmap(Image);

 aBitmap->Canvas->BeginScene();
 aRectF = RectF(aBitmap->Width - Form1->Image1->Bitmap->Width, aBitmap->Height -
	Form1->Image1->Bitmap->Height,	aBitmap->Width, aBitmap->Height);
 aBitmap->Canvas->DrawBitmap(Form1->Image1->Bitmap, Form1->Image1->Bitmap->BoundsF, aRectF, 1, true);
 aBitmap->Canvas->EndScene();

 Image1->Bitmap->Assign(aBitmap.get());

 //сохранить в галерею
 _di_IFMXPhotoLibrary Service;
 if (TPlatformServices::Current->SupportsPlatformService(__uuidof(IFMXPhotoLibrary), &Service))
	{
	   Service->AddImageToSavedPhotosAlbum(Image1->Bitmap);
	}
}   

photo_2016-10-20_17-47-41.jpg

Image1 - TImage с конечным результатом

Image2 - с логотипом

Ссылка на комментарий
  • 0

(iOS)

Интересная особенность. У акшина TakePhotoFromCameraAction1 стоит NeedSaveToAlbum=true. Т.е. снимок автоматически сохраняется на телефоне. Так вот на телефоне снимок сохраняется без логотипа. Не критично, но не понятно. :)

Ссылка на комментарий
  • 0
  • Модераторы
11 минут назад, Kitty сказал:

(iOS)

Интересная особенность. У акшина TakePhotoFromCameraAction1 стоит NeedSaveToAlbum=true. Т.е. снимок автоматически сохраняется на телефоне. Так вот на телефоне снимок сохраняется без логотипа. Не критично, но не понятно. :)

все правильно. сохраняется оригинальный файл, который приходит параметром Image, а наложение уже идет после.

можете поставить NeedSaveToAlbum=false и сами сохранить картинку в галерее

P.S. только как сохранять в IOS я незнаю. нужно смотреть исходники

Ссылка на комментарий
  • 0

Тогда беру код из документации:

http://docwiki.embarcadero.com/Libraries/Berlin/en/FMX.MediaLibrary.IFMXPhotoLibrary.AddImageToSavedPhotosAlbum

#include <FMX.MediaLibrary.hpp>

//***
if (TPlatformServices::Current->SupportsPlatformService(__uuidof(IFMXPhotoLibrary), &Service))//<-- ошибка
	{
	   Service->AddImageToSavedPhotosAlbum(Image1->Bitmap);
	}

А он выдает почему то ошибки компиляции:

[bcciosarm Error] UnitCamera.cpp(42): cannot take the address of an rvalue of type 'System::Beacon::TKindofScanFilter'

[bcciosarm Error] UnitCamera.cpp(44): member reference type 'System::Beacon::TKindofScanFilter' is not a pointer

Комментирую код и ошибка пропадает...

Изменено пользователем Kitty
Ссылка на комментарий
  • 0

Как-то оф.пример не до конца выписан:

IFMXPhotoLibrary Service;
 if (TPlatformServices::Current->SupportsPlatformService(__uuidof(IFMXPhotoLibrary), &Service))
	{
	   Service->AddImageToSavedPhotosAlbum(Image1->Bitmap);
	}

[bcciosarm Error] UnitCamera.cpp(42): variable type 'Fmx::Medialibrary::IFMXPhotoLibrary' is an abstract class

Сейчас покопаюсь в папке Sample...
 

 

 

Ссылка на комментарий
  • 0

Правильно ли поведение на андроиде - фотография без логотипа падает в папку Камера и в этой папке это фотография без логотипа. Одновременно с этим фотография попадает в паку Saved Photos и как положено с логотипом на фото. Т.е. на андроиде мы имеем фото в двух местах?

void __fastcall TFormCamera::TakePhotoFromCameraAction1DidFinishTaking(TBitmap *Image)

{
 //умный указатель чтобы не использовать delete
 std::unique_ptr<TBitmap> aBitmap(new TBitmap());
 TRectF aRectF;

 aBitmap->SetSize(Image->Width, Image->Height);
 aBitmap->CopyFromBitmap(Image);

 aBitmap->Canvas->BeginScene();
 aRectF = RectF(aBitmap->Width - Form1->Image1->Bitmap->Width, aBitmap->Height -
	Form1->Image1->Bitmap->Height,	aBitmap->Width, aBitmap->Height);
 aBitmap->Canvas->DrawBitmap(Form1->Image1->Bitmap, Form1->Image1->Bitmap->BoundsF, aRectF, 1, true);
 aBitmap->Canvas->EndScene();

 Image1->Bitmap->Assign(aBitmap.get());

 //сохранить в галерею
 _di_IFMXPhotoLibrary Service;
 if (TPlatformServices::Current->SupportsPlatformService(__uuidof(IFMXPhotoLibrary), &Service))
	{
	   Service->AddImageToSavedPhotosAlbum(Image1->Bitmap);
	}
}   

 

Изменено пользователем Kitty
Ссылка на комментарий
  • 0
  • Модераторы
28 минут назад, Kitty сказал:

Правильно ли поведение на андроиде - фотография без логотипа падает в папку Камера и в этой папке это фотография без логотипа. Одновременно с эти фотография попадает в паку Saved Photos и как положено с логотипом на фото. Т.е. на андроиде мы имеем фото в двух местах?

да поведение подтвердилось, от параметра NeedSaveToAlbum никак не зависит

Ссылка на комментарий
  • 0

И все таки этот метод не совсем подходит. В папку Камера картинка попадает с оригинальным разрешением 2592х4608, а в папку Saved Photos оно попадает масштабированное  до 324х576 (т.е. согласно размерам компонента Image на форме). Как сделать так, чтобы изображение оставалось в оригинальном размере как и получено с камеры?

Ссылка на комментарий
  • 0
  • Модераторы
2 минуты назад, Kitty сказал:

И все таки этот метод не совсем подходит. В папку Камера картинка попадает с оригинальным разрешением 2592х4608, а в папку Saved Photos оно попадает масштабированное  до 324х576 (т.е. согласно размерам компонента Image на форме). Как сделать так, чтобы изображение оставалось в оригинальном размере как и получено с камеры?

Попробуйте выставить MaxHeight, MaxWidth больше в экшене

Ссылка на комментарий
  • 0

Дополнительно обнаружено на андроиде странное поведение... Получаем фотографию с логотипом, убираем приложение в фон, возвращаем приложение и логотип на фото пропадает...:o

Изменено пользователем Kitty
Ссылка на комментарий
  • 0
  • Модераторы
5 минут назад, Kitty сказал:

Дополнительно обнаружено на андроиде странное поведение... Получаем фотографию с логотипом, убираем приложение в фон, возвращаем приложение и логотип на фото пропадает...:o

такое поведение когда используется Assign, поэтому везде нужно заменить на CopyFromBitmap (не забываем что там используется копирование один-в-один, т.е. размеры должны быть одинаковы у обоих Bitmap'ов)

Ссылка на комментарий
  • 0

Значит правильно так

Image1->Bitmap->Width = aBitmap->Width;
Image1->Bitmap->Height = aBitmap->Height;

Image1->Bitmap->CopyFromBitmap(aBitmap.get());

А в iOS можно оставить Image1->Bitmap->Assign(aBitmap.get()); там логотип не пропадает при переводе в фон. Все правильно?

 

Ссылка на комментарий
  • 0
  • Модераторы
1 минуту назад, Kitty сказал:

Значит правильно так

Image1->Bitmap->Width = aBitmap->Width;
Image1->Bitmap->Height = aBitmap->Height;

Image1->Bitmap->CopyFromBitmap(aBitmap.get());

А в iOS можно оставить Image1->Bitmap->Assign(aBitmap.get()); там логотип не пропадает при переводе в фон. Все правильно?

да правильно, вот так короче

Image1->Bitmap->SetSize(aBitmap->Width, aBitmap->Height);

зачем использовать разные методы для IOS/Android?

Ссылка на комментарий
  • 0

Спасибо. Я не могу понять, что происходит когда мы делимся фотографией в вайбере из Image1->Bitmap

void __fastcall TFormCamera::ShowShareSheetAction1BeforeExecute(TObject *Sender)
{

 ShowShareSheetAction1->Bitmap->Assign(Image1->Bitmap);

}

1. Сделана фотография.

2. Поделилась фотографией в вайбере с человеком, который сидит рядом.

3. Он получил фото все нормально.

4. Вернулась в приложение и сделала новую фотографию. Все нормально.

5. Делюсь этой новой фотографией, а человек по вайберу получает снова предыдущую, а не эту новую!

И у меня в вайбере тоже все фотографии стали одинаковые как первая отправленная.

Это проблема экшен листа или что?

P.S.

В фейсбуковский месенджер пришло все нормально. Что за чудеса? :)

Ссылка на комментарий
  • 0
  • Модераторы
1 минуту назад, Kitty сказал:

Спасибо. Я не могу понять, что происходит когда мы делимся фотографией в вайбере из Image1->Bitmap


void __fastcall TFormCamera::ShowShareSheetAction1BeforeExecute(TObject *Sender)
{

 ShowShareSheetAction1->Bitmap->Assign(Image1->Bitmap);

}

1. Сделана фотография.

2. Поделилась фотографией в вайбере с человеком, который сидит рядом.

3. Он получил фото все нормально.

4. Вернулась в приложение и сделала новую фотографию. Все нормально.

5. Делюсь этой новой фотографией, а человек по вайберу получает снова предыдущую, а не эту новую!

И у меня в вайбере тоже все фотографии стали одинаковые как первая отправленная.

Это проблема экшен листа или что?

P.S.

В фейсбуковский месенджер пришло все нормально. Что за чудеса? :)

тоже самое попробуйте через CopyFromBitmap

Ссылка на комментарий
  • 0

А как в другое событие передать правильные размеры:

ShowShareSheetAction1->Bitmap->CopyFromBitmap(Image1->Bitmap);

?

Что делать std::unique_ptr<TBitmap> aBitmap(new TBitmap()); глобальной переменной?

И тогда:

void __fastcall TFormCamera::ShowShareSheetAction1BeforeExecute(TObject *Sender)
{

 Image1->Bitmap->SetSize(aBitmap->Width, aBitmap->Height);
 ShowShareSheetAction1->Bitmap->CopyFromBitmap(Image1->Bitmap);

}

Так?

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...