Suite

Transparence d'arrière-plan IRasterLayer en C++ avec ArcObjects 10.x .NET

Transparence d'arrière-plan IRasterLayer en C++ avec ArcObjects 10.x .NET


J'ai un IRasterLayer géoréférencé qui affiche les données d'un fichier PPM sans canal alpha. J'essaie de spécifier une couleur qui doit être traitée comme transparente. Dans ArcMap, il est possible de définir une couleur spécifique pour qu'elle soit transparente, mais je n'ai pas encore trouvé d'exemple C++ fonctionnel pour ArcObjects 10.x .NET.

J'utilise l'interface COM C++ et j'ai essayé d'y parvenir en créant un RasterRGBRenderer selon ce post. L'exemple VB.NET revendiqué passe un tableau de doubles dans IRasterStretch.BackgroundValues ​​qui n'est pas compatible avec l'interface 10.1 documentée.
Malheureusement, la documentation dans ce domaine est pauvre, et ces échantillons sont très datés. La documentation ne précise même pas quel type de COM VARIANT est nécessaire lorsque des VARIANTES sont attendues.

Veuillez indiquer comment spécifier la transparence de l'arrière-plan à l'aide de C++ dans ArcObjects 10.x .NET

Éditer: À titre de test, j'ai tenté de définir le blanc BackgroundValue pour qu'il s'affiche en rouge en utilisant ce qui suit, cela n'a pas fonctionné (Cela fonctionne sur un test PNG avec un fond blanc, mais pas sur mon fichier PPM) :

esri::IRasterRGBRenderer2Ptr rgbRenderer; rgbRenderer.CreateInstance(__uuidof(esri::RasterRGBRenderer)); IRasterRendererPtr rasterRenderer(rgbRenderer); rasterRenderer->Raster = rasterLayer->Raster; hr = rasterLayer->putref_Renderer(rasterRenderer); IRgbColorPtr backgroundColor; backgroundColor.CreateInstance(__uuidof(esri::RgbColor)); backgroundColor->put_RGB(RGB(255, 0, 0)); // Rouge vif pour tester CComSafeArray backgroundValue; backgroundValue.Create(3); backgroundValue.SetAt(0, 255.0); backgroundValue.SetAt(1, 255.0); backgroundValue.SetAt(2, 255.0); CComVariant varBackgroundValue(backgroundValue); IRasterStretch2Ptr stretch(rasterRenderer); hr = stretch->put_Background(VARIANT_TRUE); hr = stretch->putref_BackgroundColor(backgroundColor); hr = stretch->put_BackgroundValue(varBackgroundValue); rasterRenderer->Mise à jour();

Je peux confirmer que BackgroundValue est correctement défini. L'appel de get_BackgroundValue renvoie toujours un tableau VARIANT de doubles et ceux-ci incluent les valeurs correctes si j'obtiens après avoir appelé put. Le rendu est également confirmé comme étant correctement défini comme si je désactivais l'une des bandes à l'aide du pointeur du rendu qui est clairement visible


J'ai été confronté au problème l'année dernière et j'ai dû apprendre : la preuve du pudding est dans le fait de manger :-o double ou tableau de double… c'est la pire des choses… peut-être que mon extrait de code aide un peu.

if (catLyrRenderer est IRasterRGBRenderer) { objet ob = null; double[] colVals = new double[bands.Count]; for (int i = 0; i < bands.Count; i++) { ob = raster2.GetPixelValue(i, col, row); if (ob != null) colVals[i] = (double)(byte)ob; } (catLyrRenderer comme IRasterStretch2).Background = true; (catLyrRenderer comme IRasterStretch2).BackgroundColor = ((IRasterDisplayProps)catLyrRenderer).NoDataColor; (catLyrRenderer comme IRasterStretch2).BackgroundValue = colVals; catLyrRenderer.Update(); } else if (catLyrRenderer est IRasterStretchColorRampRenderer) { objet ob = null; ob = raster2.GetPixelValue(0, col, ligne); (catLyrRenderer comme IRasterStretch2).Background = true; (catLyrRenderer comme IRasterStretch2).BackgroundColor = ((IRasterDisplayProps)catLyrRenderer).NoDataColor; (catLyrRenderer comme IRasterStretch2).BackgroundValue = ob; catLyrRenderer.Update(); }

Il semble que cela ait été causé par un problème d'arrondi au sein d'ESRI, car bien que l'interface COM renvoie toujours un tableau de doubles, peu importe ce que vous lui envoyez (et que la définition d'un tableau de doubles a fonctionné pour un PNG fait à la main), l'arrière-plan de mon fichier PPM ne changerait que si BackgroundValue était défini sur un tableau d'entiers. Dans ce format, la mise à l'échelle RVB était dans la plage normale de 0 à 255 et le réglage de la transparence était aussi trivial que de générer un IColor avec un jeu de transparence ou de réutiliser la valeur NoDataColor selon le message de schmiddor. Solution de travail :

esri::IRasterRGBRenderer2Ptr rgbRenderer; rgbRenderer.CreateInstance(__uuidof(esri::RasterRGBRenderer)); IRasterRendererPtr rasterRenderer(rgbRenderer); rasterRenderer->Raster = rasterLayer->Raster; hr = rasterLayer->putref_Renderer(rasterRenderer); esri::IRasterDisplayPropsPtr displayProps(rasterRenderer); esri::IColorPtr noDataColor; hr = displayProps->get_NoDataColor(&noDataColor); CComSafeArray backgroundValue; backgroundValue.Create(3); backgroundValue.SetAt(0, 255); backgroundValue.SetAt(1, 255); backgroundValue.SetAt(2, 255); CComVariant varBackgroundValue(backgroundValue); IRasterStretch2Ptr stretch(rasterRenderer); hr = stretch->put_Background(VARIANT_TRUE); hr = stretch->putref_BackgroundColor(noDataColor); hr = stretch->put_BackgroundValue(varBackgroundValue); rasterRenderer->Mise à jour();