Android中的椭圆梯度

Android中的椭圆梯度,android,graphics,gradient,shape,Android,Graphics,Gradient,Shape,我知道如何设置和显示椭圆形。我知道如何对这个形状应用渐变。我搞不懂的是如何得到一个椭圆形的渐变来匹配形状 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > <gradient android:startColor="#66FF

我知道如何设置和显示椭圆形。我知道如何对这个形状应用渐变。我搞不懂的是如何得到一个椭圆形的渐变来匹配形状

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="oval" >
    <gradient
        android:startColor="#66FFFFFF"
        android:endColor="#00FFFFFF"
        android:gradientRadius="100"
        android:type="radial" />
</shape>

如果你可以想象,这个梯度在中间有一个半透明的白色辉光,然后在边缘消失到α零。我需要让它变成椭圆形,而不仅仅是圆形渐变。如何实现这一点?

一种“愚蠢但有效”的方法是绘制椭圆轮廓,然后绘制多个具有相同“中心”的嵌套椭圆,其大小和颜色随着椭圆变小而变化,一直到一个像素的椭圆。
如果你自定义你的梯度代码,插值的颜色在HSV,而不是在RVB

这很困难,因为以这种方式定义的可绘制项在运行时绘制自己,以适应放置它们的空间。如果您必须在代码中执行此操作,那么最好的解决方案是采用您在XML中定义的可绘制形状,并将其绘制到画布或位图中作为一个完美的圆。此时,渐变图案将跟随形状轮廓。一旦形状被绘制到静态上下文中,您可以将形状添加到视图中(例如,作为背景),当它试图适应视图边界时,会将其扭曲成椭圆形。因为你有一个图像,整个东西会按比例扭曲


希望这种方法不会太糟糕。

我建议使用更“直接”的绘图方法。如果你可以一个像素一个像素地画渐变,那么你只需要记住这一点就可以了

  • 圆形渐变颜色与
    r
  • 椭圆(椭圆形)渐变颜色与
    r1+r2
在这里:

r-到圆心的距离

r1,r2-到椭圆两个焦点的距离

编辑: 考虑这个像素着色器代码:

uniform sampler2D tex;

void main()
{
    vec2 center = vec2(0.5,0.5);
    float len = 1.3*(distance(gl_TexCoord[0].xy,center));
    vec2 foc1 = vec2(len,0.);
    vec2 foc2 = vec2(-len,0.);
    float r = distance(center+foc1,gl_TexCoord[0].xy) +
             distance(center+foc2,gl_TexCoord[0].xy);
    float k = pow(r*0.9,1.3);
    vec4 color = vec4(k,k,k,1.);
    gl_FragColor = color;
}
你会得到类似这样的结果:

祝你好运


<?xml version="1.0" encoding="utf-8"?>



我发现的另一个解决方法是使用scaleX=“1.x”或scaleY=“1.x”。但是,这与形状不匹配。

标记为“如果必须在代码中执行此操作”,请更正。我发现它比图像简单得多,质量也高得多,这让我想起了这一点。这是我对你想法的实现:这也许可以,但似乎很昂贵。这取决于每像素计算的执行方式。如果在GPU端执行(作为梯度计算像素着色器)-那么它的速度就像闪电一样快:)此建议可以正常工作,但请注意,您添加的每一层都是GPU必须绘制到屏幕上的另一层。我试过一次,整个应用程序都停止了。我解决了一个类似的问题,在绘制
GradientDrawable
之前调用了
Canvas\scale
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="oval" >
    <gradient
        android:startColor="#66FFFFFF"
        android:endColor="#00FFFFFF"
        android:gradientRadius="100"
        android:type="radial" />
</shape>