博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NinePatchChunk.java分析
阅读量:6955 次
发布时间:2019-06-27

本文共 7068 字,大约阅读时间需要 23 分钟。

最近在Swing中使用.9图片,用到了NinePatchChunk.java文件,但是发现有时会出现无法完美展示的情况,决定修复一下这个问题,顺便研究一些.9的绘制过程

通过分析发现draw函数先是计算出固定宽高大小,再计算出拉升区域大小,最后遍历固定大小和拉伸大小的矩形,进行拉升的覆盖。

在分析的时候发现,我所遇到的bug是通过计算固定高得到拉伸高度时,如果有一边被填满就无法计算准确这个值引起的。

这里:

int remainderHorizontal = 0;        int remainderVertical = 0;        if (mFixed.size() > 0) {            int start = mFixed.get(0).y;            for (Rectangle rect : mFixed) {                if (rect.y > start) {                    endRow = true;                    measuredWidth = true;                }                if (!measuredWidth) {                    remainderHorizontal += rect.width;                }                if (endRow) {                    remainderVertical += rect.height;                    endRow = false;                    start = rect.y;                }            }        }        data.mRemainderHorizontal = scaledWidth - remainderHorizontal;        data.mRemainderVertical = scaledHeight - remainderVertical;

解决方法之一就是不使用填满边的.9图。当然也可以修改代码来解决。

 

 

绘制的代码:

private void draw(BufferedImage image, Graphics2D graphics2D, int x, int y, int scaledWidth,            int scaledHeight) {        if (scaledWidth <= 1 || scaledHeight <= 1) {            return;        }        Graphics2D g = (Graphics2D)graphics2D.create();        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,                RenderingHints.VALUE_INTERPOLATION_BILINEAR);        try {            if (mPatches.size() == 0) {                g.drawImage(image, x, y, scaledWidth, scaledHeight, null);                return;            }            g.translate(x, y);            x = y = 0;            DrawingData data = computePatches(scaledWidth, scaledHeight);            int fixedIndex = 0;            int horizontalIndex = 0;            int verticalIndex = 0;            int patchIndex = 0;            boolean hStretch;            boolean vStretch;            float vWeightSum = 1.0f;            float vRemainder = data.mRemainderVertical;            vStretch = mVerticalStartWithPatch;            while (y < scaledHeight - 1) {                hStretch = mHorizontalStartWithPatch;                int height = 0;                float vExtra = 0.0f;                float hWeightSum = 1.0f;                float hRemainder = data.mRemainderHorizontal;                while (x < scaledWidth - 1) {                    Rectangle r;                    if (!vStretch) {                        if (hStretch) {                            r = mHorizontalPatches.get(horizontalIndex++);                            float extra = r.width / data.mHorizontalPatchesSum;                            int width = (int) (extra * hRemainder / hWeightSum);                            hWeightSum -= extra;                            hRemainder -= width;                            g.drawImage(image, x, y, x + width, y + r.height, r.x, r.y,                                    r.x + r.width, r.y + r.height, null);                            x += width;                        } else {                            r = mFixed.get(fixedIndex++);                            g.drawImage(image, x, y, x + r.width, y + r.height, r.x, r.y,                                    r.x + r.width, r.y + r.height, null);                            x += r.width;                        }                        height = r.height;                    } else {                        if (hStretch) {                            r = mPatches.get(patchIndex++);                            vExtra = r.height / data.mVerticalPatchesSum;                            height = (int) (vExtra * vRemainder / vWeightSum);                            float extra = r.width / data.mHorizontalPatchesSum;                            int width = (int) (extra * hRemainder / hWeightSum);                            hWeightSum -= extra;                            hRemainder -= width;                            g.drawImage(image, x, y, x + width, y + height, r.x, r.y,                                    r.x + r.width, r.y + r.height, null);                            x += width;                        } else {                            r = mVerticalPatches.get(verticalIndex++);                            vExtra = r.height / data.mVerticalPatchesSum;                            height = (int) (vExtra * vRemainder / vWeightSum);                            g.drawImage(image, x, y, x + r.width, y + height, r.x, r.y,                                    r.x + r.width, r.y + r.height, null);                            x += r.width;                        }                    }                    hStretch = !hStretch;                }                x = 0;                y += height;                if (vStretch) {                    vWeightSum -= vExtra;                    vRemainder -= height;                }                vStretch = !vStretch;            }        } finally {            g.dispose();        }    }

 

 

计算patch长度和固定长度的remainder的代码

private DrawingData computePatches(int scaledWidth, int scaledHeight) {        DrawingData data = new DrawingData();        boolean measuredWidth = false;        boolean endRow = true;        int remainderHorizontal = 0;        int remainderVertical = 0;        if (mFixed.size() > 0) {            int start = mFixed.get(0).y;            for (Rectangle rect : mFixed) {                if (rect.y > start) {                    endRow = true;                    measuredWidth = true;                }                if (!measuredWidth) {                    remainderHorizontal += rect.width;                }                if (endRow) {                    remainderVertical += rect.height;                    endRow = false;                    start = rect.y;                }            }        }        data.mRemainderHorizontal = scaledWidth - remainderHorizontal;        data.mRemainderVertical = scaledHeight - remainderVertical;        data.mHorizontalPatchesSum = 0;        if (mHorizontalPatches.size() > 0) {            int start = -1;            for (Rectangle rect : mHorizontalPatches) {                if (rect.x > start) {                    data.mHorizontalPatchesSum += rect.width;                    start = rect.x;                }            }        } else {            int start = -1;            for (Rectangle rect : mPatches) {                if (rect.x > start) {                    data.mHorizontalPatchesSum += rect.width;                    start = rect.x;                }            }        }        data.mVerticalPatchesSum = 0;        if (mVerticalPatches.size() > 0) {            int start = -1;            for (Rectangle rect : mVerticalPatches) {                if (rect.y > start) {                    data.mVerticalPatchesSum += rect.height;                    start = rect.y;                }            }        } else {            int start = -1;            for (Rectangle rect : mPatches) {                if (rect.y > start) {                    data.mVerticalPatchesSum += rect.height;                    start = rect.y;                }            }        }        return data;    }

 

 

转载于:https://www.cnblogs.com/TLightSky/p/3479961.html

你可能感兴趣的文章
正则表达式相关
查看>>
[转]hisi mmz模块驱动讲解
查看>>
二叉树非递归先中后序遍历 及 非递归交换二叉树两个孩子的位置
查看>>
项目总结23:POI生成Excel文件并浏览器导出
查看>>
RabbitMQ 端口号解析
查看>>
当在java不同包中有相同名字的servlet时,在web.xml中该如何配置?
查看>>
仿当当网鼠标经过图片翻转
查看>>
ubuntu 创建桌面快捷方式
查看>>
第三次作业
查看>>
洛谷P5055 【模板】可持久化文艺平衡树(FHQ Treap)
查看>>
【WebApi】通过HttpClient调用Web Api接口
查看>>
iphone-common-codes-ccteam源代码 CCUIViewController.m
查看>>
阿里云乌班图安装JDK\MYSQL\REDIS
查看>>
git冲突解决
查看>>
探索性测试实例-方法篇
查看>>
数论之 莫比乌斯函数
查看>>
AtCoder Regular Contest 096
查看>>
vue-music 关于Search(搜索页面)-- 搜索结果优化
查看>>
Django:URL,Views,Template,Models
查看>>
常用工具
查看>>