UE4中对图片裁剪压缩

19 篇文章 1 订阅

一:使用说明
对已拍照的FColor数据进行裁剪、压缩的操作,达到减少内存的效果:
PC上原截图 约900+kb
PC上裁剪截图 约200+kb
PC上裁剪截图加转格式 约130kb
PC上裁剪截图加转格式加压缩 约13kb
下面提供示例接口,有需要可以进行参考修改

二、调用示例:
C侧:
1、命令行方式截图

void UPhotoSubsys::CaptureScreenShot()
{
	if (GEngine && GEngine->GameViewport)
	{
		GCaptureDelaHandle = UGameViewportClient::OnScreenshotCaptured().AddUObject(this, &UPhotoSubsys::OnCaptureScreenShotComplete);
		//命令行截屏
		FString cmdStr = GetShotCmdStr();
		GEngine->GameViewport->Exec(GetWorld(), *cmdStr, *GLog);
	}
}

void UPhotoSubsys::OnCaptureScreenShotComplete(int32 InWidth, int32 InHeight, const TArray<FColor>& InColors)
{
	if (ImmediatelySave()) //直接保存
	{
		bool bSaveSucceed = false;
		TArray<uint8> PNGData;
		FImageUtils::CompressImageArray(InWidth, InHeight, InColors, PNGData);
		FString pngFilePath = GetSaveFilePath();
		bSaveSucceed = FFileHelper::SaveArrayToFile(PNGData, *pngFilePath);
		OnEndSaveImageFileInC(bSaveSucceed, pngFilePath);
	}
	else
	{
		//将数据传递给Lua侧,进行后续处理,本文采用这种方式
		OnEndCaptureScreenShot(InWidth, InHeight, InColors);	
	}
}

2、根据尺寸保存压缩jpg

bool UPhotoSubsys::SaveImageArrayWithJPG(int32 InWidth, int32 InHeight, int32 Quality, const TArray<FColor>& InColors, const FString& ScreenShotName)
{
	IImageWrapperModule& ImageWrapperModule = FModuleManager::Get().LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
	IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
	if (ImageWrapper->SetRaw(InColors.GetData(), InColors.Num() * sizeof(FColor), InWidth, InHeight, ERGBFormat::BGRA, 8))
	{
		return FFileHelper::SaveArrayToFile(ImageWrapper->GetCompressed(Quality), *ScreenShotName);
	}
	return false;
}

3、通过传参路径和jpg/png 读取本地图片转换成UTexture2D

UTexture2D* UBlueprintFunctionLibrary::LoadTexture2dFromFile(const FString& FilePath, UTexture2D* texture2d, int ImageFormat)
{
	TArray<uint8> ImageResultData;
	if (FFileHelper::LoadFileToArray(ImageResultData, *FilePath) == false)//读取图片的二进制数据
		return nullptr;

	//EImageFormat ImageFormat = EImageFormat::PNG;
	IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>("ImageWrapper");
	TSharedPtr<IImageWrapper> ImageWrapperptr = ImageWrapperModule.CreateImageWrapper(EImageFormat(ImageFormat));//创建对应格式图片壳子

	const bool PtrIsValid = ImageWrapperptr.IsValid();
	if (PtrIsValid && ImageWrapperptr->SetCompressed(ImageResultData.GetData(),ImageResultData.GetAllocatedSize()))
	{
		TArray64<uint8> OutRawData;
		ImageWrapperptr->GetRaw(ERGBFormat::BGRA, 8, OutRawData); //按规则提取数据

		if (texture2d == nullptr ||
			texture2d->GetSizeX() != ImageWrapperptr->GetWidth() ||
			texture2d->GetSizeY() != ImageWrapperptr->GetHeight())
			texture2d = UTexture2D::CreateTransient(ImageWrapperptr->GetWidth(), ImageWrapperptr->GetHeight(), PF_B8G8R8A8);

		if (texture2d)
		{
			void* TextureData = texture2d->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
			FMemory::Memcpy(TextureData, OutRawData.GetData(),OutRawData.Num());//将数据写入*TextureData
			texture2d->PlatformData->Mips[0].BulkData.Unlock();
			texture2d->UpdateResource();
		}
	}
	return texture2d;
}

Lua侧:

裁剪

function UPhotoSubsys:ClipPhoto(InWidth, InHeight, InColors, startX, startY, targetX, targetY, fileName)
    if startX > InWidth or targetX > InWidth or startY > InHeight or targetY > InHeight then
        print("ClipPhoto Failed: Invaild InputParms")
        return false
    end
    local baseColorTable = InColors:ToTable()
    local nColors = UE4.TArray(UE4.FColor)
    for y = 1, targetY do
        for x = 1, targetX do
            if y > startY and x > startX then
                local baseColor = UE4.FColor
                baseColor = baseColorTable[(y * InWidth + x)]
                nColors:Add(baseColor)
            end
        end
    end

    local rootPath = GetAbsoluteSavePath("Snapshot/")
    local filePath = rootPath .. fileName
    local bSaved = false

    --压缩jpg
    if UPhotoSubsys.SaveImageArrayWithJPG then
        bSaved = UPhotoSubsys:SaveImageArrayWithJPG(targetX - startX, targetY - startY, 50, nColors, filePath)
    end

    return bSaved
end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值