zoukankan      html  css  js  c++  java
  • android 下 庶罩

    引用:http://www.linuxidc.com/Linux/2011-08/41106.htm

    大体需求是,有一个文字点阵,叫glyph,为单色点阵,有笔画的地方为黑色,1;无笔画的地方为白色,0;
    现在要把这个字画到屏幕,还有一个要求,要用当前颜色画;
    分析来分析去,这就是一个简单的rop3操作,或者简单一点,就是一个遮罩特效:使用glyph当遮罩,使用当前颜色画矩形,仅此而以。

    相关阅读:Android gallery滑动惯性问题 http://www.linuxidc.com/Linux/2011-01/31451.htm

    但是,目前没有在Skia中找到类似的操作,只找到SkXformode里有这样的定义:

    enum Mode {
    kClear_Mode, //!< [0, 0]
    kSrc_Mode, //!< [Sa, Sc]
    kDst_Mode, //!< [Da, Dc]
    kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Rc = Sc + (1 -
    Sa)*Dc]
    kDstOver_Mode, //!< [Sa + Da - Sa*Da, Rc = Dc + (1 -
    Da)*Sc]
    kSrcIn_Mode, //!< [Sa * Da, Sc * Da]
    kDstIn_Mode, //!< [Sa * Da, Sa * Dc]
    kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)]
    kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)]
    kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc]
    kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)]
    kXor_Mode, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1-Sa)* Dc]
    ......

    基本上看不懂,光看公式,没法知道到底是个什么效果;看来只有使用这些东西来模拟遮罩效果了。
    试验来试验去,下面的代码可以实现:

    1 首先,把单色位图转换成32位
    static void depth1to32(const uint16 * data, uint8 * out,
    uint8
    *
    end)
    {
    uint16 pixel;
    uint32 value;
    ......
    // glyph : src SkBitmap
    // bitmap : dst SkBitmap
    int width;
    int height;
    width = glyph->width();
    height = glyph->height();
    uint8 *sbits;
    sbits = (uint8 *)data;
    int sstride;
    sstride = (width + 7) / 8;
    uint8 *sline;
    sline = sbits;
    // check format
    uint8 *dbits;
    dbits = (uint8 *)out;
    int dstride;
    dstride = bitmap->rowBytes();
    int dbpp; // bytes per pixel
    dbpp = bitmap->bytesPerPixel();
    uint8 *dline;
    dline = dbits;
    while (height--)
    {
    int w = width;
    uint8 *dline1 = dline;
    uint8 *sline1 = sline;
    while(w > 0)
    {
    uint8 pixel8;
    pixel8 = *(sline1++);
    for(int i = 0; i < (w < 8 ? w : 8); i++)
    {
    uint8 c = 1 < < (7 - i);
    if(pixel8 & c)
    {
    *(dline1++) = 0;
    *(dline1++) = 0;
    *(dline1++) = 0;
    // 这个地方,如果最高两个字节是0,则表示透明
    *(dline1++) = 0xFF;
    }
    else
    {
    *(dline1++) = 0xff;
    *(dline1++) = 0xff;
    *(dline1++) = 0xff;
    // 这个地方,如果最高两个字节是0,则表示透明
    *(dline1++) = 0;
    }
    }
    w -= 8;
    }
    dline += dstride;
    sline += sstride;
    }
    }
    ......

    2 使用当前颜色转换遮罩
    SkBitmap *srcbmp = (SkBitmap*)(bitmap);
    SkPaint paint;
    SkCanvas canvas(*srcbmp);
    paint.setXfermodeMode(SkXfermode::kSrcIn_Mode);
    paint.setColor(display->foreColor);
    SkRect rect = { 0, 0, srcbmp->width(),
    srcbmp->height()};
    canvas.drawRect(rect, paint);
    自此,srcbmp已经变成了当前颜色表示的字符点阵

    3 把字符画到屏幕
    SkShader* s = SkShader::CreateBitmapShader(*srcbmp,
    SkShader::kClamp_TileMode,
    SkShader::kClamp_TileMode);
    SkMatrix matrix;
    matrix.reset();
    matrix.postTranslate(x, y);
    SkShader *shader = (SkShader *)s;
    shader->setLocalMatrix(matrix); // 设置原点
    SkPaint *paint = (SkPaint *)paint;
    paint->setShader(shader)->unref();
    paint->setXfermodeMode(SkXfermode::kSrcOver_Mode);
    paint->setColor(display->foreColor);
    SkRect rect = { x, y, x + w, y + h};
    canvas->drawRect(rect, *paint);

    这段代码,相当于把一个部分区域透明的pattern画到屏幕上
    这样,我们就实现了字符遮罩的功能,使用当前颜色把字符画到屏幕上了。
    当然,我们只是画了一个单色字符,其实也可以画很复杂的图案,类似于PS和Flash里的遮罩层的效果。
    以上代码是示意代码,因此有些地方明显无法编译,有些地方明显多此一举,请注意。
    另,Skia有类似Mask的概念,但看来看去,好像没有我们这里说的遮罩功能。
    如果大家有更好的实现方法,也请告诉我一下。

  • 相关阅读:
    配置JAVA的环境变量
    Navicat Premium v12.0.23.0 安装,使用激活码激活
    mysql 5.7.33安装教程
    查看mysql服务
    postman测试post请求参数是List entity后端用@RequestBody接受lIst entity方式
    最简单的MySQL安装教程(数据库免安装版,免安装版,亲测好用) mysql-5.7.33-winx64.zip
    mysql数据库安装5.7.33
    java删除附件图片
    java生成条形码
    最高的牛
  • 原文地址:https://www.cnblogs.com/sode/p/2875907.html
Copyright © 2011-2022 走看看