UE4C++获取鼠标像素点颜色与获取图片想像素点

UE4C++获取鼠标像素点颜色与获取图片像素点

  • 注:代码很简单,此章直接附上,代码也给大家注释好了
  • .h头文件
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "PixelBlueprintFunctionLibrary.generated.h"


UCLASS()
class GAME_SANDBOX_API UPixelBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:
	//获取鼠标对应像素点
	UFUNCTION(BlueprintCallable)
		static FColor  GetMousePointColor(float x = 0.f, float y = 0.f, bool InUsingMosuePoint = true);
	//获取图片像素点Texture2D
	UFUNCTION(BlueprintCallable, category = "GetPicPixel")
		static TArray<FColor> GetPictureRGBPixel(class UTexture2D* RGBTexture, int& OutX, int& OutY);
};
  • .CPP文件
// Fill out your copyright notice in the Description page of Project Settings.


#include "PixelBlueprintFunctionLibrary.h"
#include "Windows/MinimalWindowsApi.h"
#include "Misc/FeedbackContextMarkup.h"
#include "Windows/COMPointer.h"
#include "Windows/AllowWindowsPlatformTypes.h"
#include <commdlg.h>
#include <shlobj.h>
#include "Engine/Texture2D.h"
#include "Engine/Texture.h"

FColor UPixelBlueprintFunctionLibrary::GetMousePointColor(float x, float y, bool InUsingMosuePoint)
{
	//获取当前HDC,不懂HDC的,可以看看C++窗口编程
	//::前面啥也不写,代表全局函数的调用
	HDC tempHDC = ::GetDC(NULL);
	//创建临时变量存储鼠标值
	POINT pt1;
	//判断是否用鼠标位置获取,不是的话,则用输入值获取,是的话用鼠标位置获取像素
	if (InUsingMosuePoint)
		GetCursorPos(&pt1);
	else { pt1.x = x; pt1.y = y; }
	//获取当前像素点颜色值
	COLORREF clr = ::GetPixel(tempHDC, pt1.x, pt1.y);
	//获取颜色的R G B值
	int R = GetRValue(clr);
	int G = GetGValue(clr);
	int B = GetBValue(clr);
	//释放当前HDC
	::ReleaseDC(NULL, tempHDC);
	//创建应当返回的颜色值
	FColor Color;
	Color.R = R;
	Color.G = G;
	Color.B = B;
	Color.A = 255;
	return Color;
}


TArray<FColor> UPixelBlueprintFunctionLibrary::GetPictureRGBPixel(UTexture2D* RGBTexture, int& OutX, int& OutY)
{
	//存放每个点的颜色值TArray64<uint8>类型,用于临时转换
	TArray64<uint8>PicData;
	//存放每个点的颜色值
	TArray<FColor>PixelColorArray;

	//读取图片的像素值R,G,G,A
	RGBTexture->Source.GetMipData(PicData, 0);
	//每四个数(RGBA)组成一个颜色数组
	FColor* Colors = (FColor*)PicData.GetData();

	//获取图片的长宽
	OutX = RGBTexture->Source.GetSizeX();
	OutY = RGBTexture->Source.GetSizeY();
	//将颜色转换成FColor类型存放在PixelColorArray中
	for (int y = 0; y < OutY; y++)
	{
		for (int x = 0; x < OutX; x++)
		{
			FColor PixelColor = Colors[y * OutX + x];
			PixelColorArray.Add(PixelColor);
		}
	}
	return PixelColorArray;
}

由于Source在打包时候不可用,因此此处采用另一种方式进行获取图片

TArray<FColor> UPixelBlueprintFunctionLibrary::GetPictureRGBPixel(UTexture2D* RGBTexture, int& OutX, int& OutY)
{
	TArray<FColor>PixelColorArray;//存放每个点的颜色值
	const FColor* Colors = static_cast<FColor*>(RGBTexture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_ONLY));
	OutX = RGBTexture->GetSizeX();
	OutY = RGBTexture->GetSizeY();
	for (int y = 0; y < OutY; y++)
	{
		for (int x = 0; x < OutX; x++)
		{
			FColor PixelColor = Colors[y * OutX + x];
			PixelColorArray.Add(PixelColor);
		}
	}
	return PixelColorArray;
}

static_cast<FColor*>(RGBTexture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_ONLY));可能返回值为空,因此,此时我们需要设置RGBTexture的一些参数,然后读取数据之后再改回来

TArray<FColor> UPixelBlueprintFunctionLibrary::GetPictureRGBPixel(UTexture2D* RGBTexture, int& OutX, int& OutY)
{
	if (!IsValid(RGBTexture)|| !RGBTexture->PlatformData)
		return TArray<FColor>();

	TArray<FColor>ColorArray;

	TextureCompressionSettings OldCompressionSettings = RGBTexture->CompressionSettings;
	TextureMipGenSettings OldMipGenSettings = RGBTexture->MipGenSettings; 
	bool OldSRGB = RGBTexture->SRGB;
	RGBTexture->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
	RGBTexture->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
	RGBTexture->SRGB = false;
	RGBTexture->UpdateResource();
	const FColor* Colors = static_cast<const FColor*>(RGBTexture->PlatformData->Mips[0].BulkData.LockReadOnly());

	OutX = RGBTexture->GetSizeX();
	OutY = RGBTexture->GetSizeY();
	for (int y = 0; y < OutY; y++)
	{
		for (int x = 0; x < OutX; x++)
		{
			FColor PixelColor = Colors[y * OutX + x];
			ColorArray.Add(PixelColor);
		}
	}
	RGBTexture->PlatformData->Mips[0].BulkData.Unlock();

	RGBTexture->CompressionSettings = OldCompressionSettings;
	RGBTexture->MipGenSettings = OldMipGenSettings;
	RGBTexture->SRGB = OldSRGB;
	RGBTexture->UpdateResource();
	return ColorArray;
}

至此,我们发现打包依旧有数据是在编辑器模式下的,因此,我们手动将代码中所用到的图片设置成对应模式就行,我们发现打包出错的地方在默认的Texture2d里面是对的,因此将它注释掉就行
在这里插入图片描述

TArray<FColor> UPixelBlueprintFunctionLibrary::GetPictureRGBPixel(UTexture2D* RGBTexture, int& OutX, int& OutY)
{
	if (!IsValid(RGBTexture)|| !RGBTexture->PlatformData)
		return TArray<FColor>();

	TArray<FColor> ColorArray;

	//TextureCompressionSettings OldCompressionSettings = RGBTexture->CompressionSettings;
	//TextureMipGenSettings OldMipGenSettings = RGBTexture->MipGenSettings;
	bool OldSRGB = RGBTexture->SRGB;
	RGBTexture->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
	//RGBTexture->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
	RGBTexture->SRGB = false;
	RGBTexture->UpdateResource();
	const FColor* Colors = static_cast<const FColor*>(RGBTexture->PlatformData->Mips[0].BulkData.LockReadOnly());

	OutX = RGBTexture->GetSizeX();
	OutY = RGBTexture->GetSizeY();
	for (int y = 0; y < OutY; y++)
	{
		for (int x = 0; x < OutX; x++)
		{
			FColor PixelColor = Colors[y * OutX + x];
			ColorArray.Add(PixelColor);
		}
	}
	RGBTexture->PlatformData->Mips[0].BulkData.Unlock();

	//RGBTexture->CompressionSettings = OldCompressionSettings;
	//RGBTexture->MipGenSettings = OldMipGenSettings;
	RGBTexture->SRGB = OldSRGB;
	RGBTexture->UpdateResource();
	return ColorArray;
}
在Unreal Engine 4 (UE4) 中,使用C++获取当前服务器中的所有玩家可以通过多种方式实现。以下是一些常用的方法: ### 1. 使用`GetWorld()->GetGameState()` 如果你的游戏中有一个自定义的`GameState`类,你可以通过它来获取所有玩家的信息。 ```cpp #include "YourGameState.h" // 替换为你的GameState类头文件 void AYourClass::GetAllPlayers() { AYourGameState* GameState = Cast<AYourGameState>(GetWorld()->GetGameState()); if (GameState) { for (APlayerState* PlayerState : GameState->PlayerArray) { // 处理每个PlayerState } } } ``` ### 2. 使用`GetWorld()->GetAuthGameMode()` 如果你的游戏模式(GameMode)中有关于玩家的信息,也可以通过它来获取。 ```cpp #include "YourGameMode.h" // 替换为你的GameMode类头文件 void AYourClass::GetAllPlayers() { AYourGameMode* GameMode = Cast<AYourGameMode>(GetWorld()->GetAuthGameMode()); if (GameMode) { for (APlayerState* PlayerState : GameMode->PlayerArray) { // 处理每个PlayerState } } } ``` ### 3. 使用`GetWorld()->GetFirstPlayerController()` 如果你只需要获取第一个玩家控制器,可以使用这个方法。 ```cpp void AYourClass::GetFirstPlayer() { APlayerController* FirstPlayerController = GetWorld()->GetFirstPlayerController(); if (FirstPlayerController) { APlayerState* PlayerState = FirstPlayerController->GetPlayerState<APlayerState>(); // 处理PlayerState } } ``` ### 4. 遍历所有的`PlayerController` 如果你遍历所有的玩家控制器,可以使用以下代码: ```cpp void AYourClass::GetAllPlayers() { for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator) { APlayerController* PlayerController = Iterator->Get(); if (PlayerController) { APlayerState* PlayerState = PlayerController->GetPlayerState<APlayerState>(); if (PlayerState) { // 处理每个PlayerState } } } } ``` ### 5. 使用`TActorIterator` 你也可以使用`TActorIterator`来遍历所有的`PlayerState`对象。 ```cpp void AYourClass::GetAllPlayers() { for (TActorIterator<APlayerState> It(GetWorld()); It; ++It) { APlayerState* PlayerState = *It; // 处理每个PlayerState } } ``` 这些方法可以帮助你在UE4中使用C++获取当前服务器中的所有玩家信息。根据你的具体需求和游戏架构选择合适的方法。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值