本文介绍了如何在GPU画布FMX TImage上禁用插值,或将插值设置为“最邻近”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个缩小缩放的TImage函数,并希望在调整firemonkey TImage控件的大小时禁用插值(它需要在多个设备上工作)。

I am trying to create a pinch-to-zoom TImage function and want to disable interpolation when resizing a firemonkey TImage control (and it needs to work across multiple devices).

如果将 GlobalUseGPUCanvas设置为 True,或者在Android(我相信始终使用GPU画布)上,则在Windows上将TImage的 DisableInterpolation设置为 True不起作用。

Setting the TImage's "DisableInterpolation" to "True" doesn't work on Windows if "GlobalUseGPUCanvas" is set to "True" or on Android (which I believe always uses a GPU canvas).

通过在项目的DPR文件中将 GlobalUseGPUCanvas设置为 True并在表单的TImage上选中 DisableInterpolation,可以很容易地用Embarcadero的图像缩放示例进行重现:

This is easily reproducible with Embarcadero's Image Zoom sample by setting "GlobalUseGPUCanvas" to "True" in the project's DPR file and checking "DisableInterpolation" on the form's TImage:
http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/FMX.ImageZoom_Sample

有没有一种方法可以真正禁用GPU画布的插值,或者以某种方式将GPU重采样器设置为使用最近的邻居而不是默认算法(bicubic?bilinear? )?

Is there a way to truly disable interpolation with a GPU canvas or somehow set the GPU resampler to use nearest neighbor instead of the default algorithm (bicubic? bilinear?)?

解决方案

可以使用纹理直接在画布上绘制图像,而不是使用TImage

Instead of using a TImage, you can paint directly the image on the canvas using a Texture

您可以使用GL_NEAREST而不是GL_LINEAR(即:Texture.MagFilter)为其指定纹理。

When you will create the texture you can assign it with GL_NEAREST instead of GL_LINEAR (IE: Texture.MagFilter)

将在创建纹理的delphi函数下面(供参考):

Below the delphi function that will create the texture (for reference) :

class procedure TCustomContextOpenGL.DoInitializeTexture(const Texture: TTexture);
var
  Tex: GLuint;
begin
  if Valid then
  begin
    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1, @Tex);
    glBindTexture(GL_TEXTURE_2D, Tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    case Texture.MagFilter of
      TTextureFilter.Nearest: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
      TTextureFilter.Linear: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    end;
    if TTextureStyle.MipMaps in Texture.Style then
    begin
      case Texture.MinFilter of
        TTextureFilter.Nearest: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
        TTextureFilter.Linear: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
      end;
    end
    else
    begin
      case Texture.MinFilter of
        TTextureFilter.Nearest: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        TTextureFilter.Linear: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      end;
    end;
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Texture.Width, Texture.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nil);
    glBindTexture(GL_TEXTURE_2D, 0);
    ITextureAccess(Texture).Handle := Tex;
    if (GLHasAnyErrors()) then
      RaiseContextExceptionFmt(@SCannotCreateTexture, [ClassName]);
  end;
end;

这篇关于如何在GPU画布FMX TImage上禁用插值,或将插值设置为“最邻近”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 17:04