几个答案提到使用GradientDrawable.setDither(true)在Android中绘制平滑渐变.这对我的代码没有任何影响.知道我需要改变什么才能在我的动态壁纸中获得漂亮的渐变效果吗?
GradientDrawable gradient = new GradientDrawable(Orientation.TL_BR, colors);
gradient.setGradientType(GradientDrawable.RADIAL_GRADIENT);
gradient.setGradientRadius(canvas.getWidth() * 2);
gradient.setDither(true);
gradient.setGradientCenter(-0.1f, -0.1f);
gradient.setBounds(cb);
gradient.draw(canvas);
Run Code Online (Sandbox Code Playgroud) 在运行Android 4.0或4.0.3的模拟器上,我看到了可怕的色带,我似乎无法摆脱它.在我测试的每个其他Android版本上,渐变看起来很流畅.
我有一个配置为RGBX_8888的SurfaceView,并且渲染画布中不存在条带.如果我通过在渲染结束时叠加噪声模式来手动抖动图像,我可以使渐变再次平滑,但显然代价是我宁愿避免的性能.
因此绑带将在稍后介绍.我只能假设,在4.0+上,我的SurfaceView在被绘制和显示之间的某个点处被量化为较低的位深度,我可以从屏幕截图中看到渐变是一次步进8个值每个通道,建议量化到555(而不是565).
我将以下内容添加到我的Activity onCreate函数中,但它没有任何区别.
getWindow().setFormat(PixelFormat.RGBA_8888);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DITHER);
Run Code Online (Sandbox Code Playgroud)
我也尝试将上面的内容放在onAttachedToWindow()上,但仍然没有变化.
(我相信RGBA_8888无论如何都是2.2及以上版本的默认窗口格式,因此明确设置该格式对4.0+没有影响也就不足为奇了.)
这就留下了一个问题,如果源是8888,目的地是8888,那么引入量化/条带的原因是什么,它为什么只出现在4.0+?
非常令人费解.我想知道是否有人可以放弃一些光线?
我知道Floyd-Steinberg抖动算法不能用像素着色器实现,因为该算法是严格顺序的.但也许存在一些高度并行的抖动算法,它的视觉输出类似于Floyd-Steinberg算法?
所以问题是 - 什么是抖动算法适合在像素着色器(最好是GLSL)上实现,输出质量(非常)类似于Floyd-Steinberg抖动?
BTW.允许多次传递算法,直到不超过2次传递,并且这些传递之间的CPU开销很小.
有任何想法吗 ?
编辑:
我需要从24位颜色到21位颜色抖动.
(也就是说 - 我需要将8位/通道转换为7位/通道.)
编辑2
也许我没有很好地解释问题.所以我会尝试扩展一些确切的问题.问题是这个 - 考虑一下我们有这张照片:
我们有上面的图片,但用抖动算法处理:
现在这是测试你的抖动对我有好处的程序:
1.在Photoshop中将这些图片作为一张图片加载2层.
2.选择"图层"混合模式为"差异".
3.对图层执行"合并可见"操作,以获得一个图层.
4.执行操作=>图像/调整/均衡
之后你必须得到这样的图像:
正如你所看到的那样 - 单调红色的中间像素根本没有抖动.左右图像区域的抖动也有点不同.尝试用这种行为重建抖动算法.
我正在玩HTML5中的网络摄像头过滤器.有一个阿特金森抖动工作相当好的老派Mac感觉.
现在我正试图为1989年的Gameboy感觉制作拜耳订购的抖动选项.
我读了算法,但是我在将这个伪代码转换为JavaScript时遇到了麻烦:
for each y
for each x
oldpixel := pixel[x][y] + threshold_map_4x4[x mod 4][y mod 4]
newpixel := find_closest_palette_color(oldpixel)
pixel[x][y] := newpixel
Run Code Online (Sandbox Code Playgroud)
AS3,PHP或JS中是否有任何示例?你能解释一下发生了threshold_map_4x4[x mod 4][y mod 4]什么吗?
弄清楚了.在维基百科中,它说"例如,在单色渲染中,如果像素的值(缩放到0-9范围内)小于矩阵的相应单元格中的数字,则绘制该像素为黑色,否则,将其绘制为白色".在js中,通过平均当前像素(0-255)和地图值(15-240)并将其与阈值(通常为129)进行比较,我得到了很好的结果:
var map = (imageData.data[currentPixel] + bayerThresholdMap[x%4][y%4]) / 2;
imageData.data[currentPixel] = (map < threshold) ? 0 : 255;
Run Code Online (Sandbox Code Playgroud)
这是我使用不同算法的整个单色函数:
var bayerThresholdMap = [
[ 15, 135, 45, 165 ],
[ 195, 75, 225, 105 ],
[ 60, …Run Code Online (Sandbox Code Playgroud) 我用imread将8位灰度图像加载到八度音阶中,然后我以ascii格式保存它并获得了所有值的巨大列表.然后我用Java中的2x2矩阵对其进行抖动,并在一行上打印出每个抖动矩阵的列表.
如果我程序中像素的矩阵结果如下:
0 2
3 1
Run Code Online (Sandbox Code Playgroud)
然后我的程序生成的输出如下:
0 2 3 1
Run Code Online (Sandbox Code Playgroud)
然后,我将所有格式的矩阵都放在一行中.如何将其加载到八度音阶以查看最终的抖动图像?
我正在乱七八糟地创建一个简单的矩阵,就像我展示的第一个矩阵并将其保存到一个文件中,然后我就能将它全部放在一行并再次加载就好了.我试着用我的程序生成的矩阵替换该文件中的矩阵,但是octave似乎没有加载它.它试图加载它的矩阵根本没有改变.
我一直在寻找一种优化(即快速)算法,该算法使用抖动将24位RGB位图转换为16位(RGB565)位图.我正在寻找C/C++中的东西,我可以实际控制如何应用抖动.GDI +似乎提供了一些方法,但我不知道它们是否会抖动.并且,如果他们做了抖动,他们使用什么机制(Floyd-Steinberg?)
有没有人有一个很好的位图颜色深度转换与抖动的例子?
我正在开发一个基于桌面的PHP应用程序,我们需要捕获一个人的图像并使用Zebra GC420t打印机将其打印在标签上预期的图像应该如下图所示.
当我尝试打印时,它会输出如下图所示的输出.
我使用以下代码使用代码将rgb图像转换为图像ditheringphp
$photo_url="";
if(isset($_GET['photo'])){
$photo_url=$_GET['photo'];
}
function image2grf($filename='$photo_url', $targetname = 'R:IMAGE.GRF')
{
$info = getimagesize($filename);
$im = imagecreatefrompng($filename);
$width = $info[0]; // imagesx($im);
$height = $info[1]; // imagesy($im);
$depth = $info['bits'] ?: 1;
$threshold = $depth > 1 ? 160 : 0;
$hexString = '';
$byteShift = 7;
$currentByte = 0;
// iterate over all image pixels
for ($y = 0; $y < $height; $y++) {
for ($x = 0; $x < …Run Code Online (Sandbox Code Playgroud) 我已经实现了几个函数来将sRGB转换为CIE-L*a*b*颜色空间.
现在,我想将它用于抖动,但我不确定如何准确地辨别哪种颜色是"较低"颜色,哪一种颜色是"较高"颜色.
当在一维色彩空间(灰度)中抖动时,事情很容易.当使用误差扩散抖动时,我从我的调色板计算最接近的灰度值,并将误差添加到周围的像素,这取决于我使用的抖动矩阵类型(例如Floyd-Steinberg).由于这是一维的,所以很简单,只有这一个值.但是现在我有了这个三维颜色空间,我应该单独将错误添加到每个坐标吗?
(在这一点上,这是对我有意义的唯一方法.)
当与有序抖动矩阵抖动时,事情变得更加复杂.有序抖动矩阵定义阈值.为此,我需要知道我的托盘的"较低"像素值和"较高"像素值,就我当前要抖动的像素而言.现在,我计算到两个像素的距离,来自抖动矩阵的阈值决定在那些与相邻像素之间的值之后,该像素被抖动到较低像素,或者抖动到较高像素.
(实际的实现当然会比计算,通过使用被明智地在我的托盘选择用于量灰度颜色值的矩阵更优化.此外,像具有均匀间隔的颜色值选择托盘等)
这再次 - 在一维色彩空间中非常容易.但在CIE-L*a*b*中,没有"更高"或"更低"的值.
仅使用亮度来应用阈值矩阵,看起来非常不正确,我的托盘中可能有两种颜色相同的亮度,那么呢?
我正在开发一个与OpenGL一起使用的纹理图册打包器,我正在寻找一个开源(如果它是一个库,它会更好,但开源软件也会更好!)解决方案调色板创建/抖动的最佳结果.它确实不需要很快,但需要达到最佳效果.如果有可能生成每像素4位调色板,那将是最好的.
我对抖动感兴趣,命令抖动更精确。我花了很多时间在研究和实验上。并希望经过所有努力,我的代码能够正常工作。
我将提供执行抖动的代码和一些示例。
我的问题
这是这篇维基百科文章中抖动算法的伪代码,我的代码基于该文章。

以下是变量解释:
M(i, j)是第i行第j列c上的阈值图?是变换后的颜色,r是颜色空间中的扩散量。假设一个 RGB 调色板具有N³均匀选择的颜色,其中每个颜色坐标由一个八位字节表示,通常会选择:
现在,这是我的实现(伪代码):
ditherMatrix = 4x4; // By 4x4 I mean the normal 4x4 dither matrix from the wikipedia article
ditherMatrixSize = 4;
offset = (ditherMatrixSize * (ditherMatrixSize / 2) - 0.5);
/* In the wiki article it uses 0.5 as an offset,
but I have to do this instead.
Is this correct? …Run Code Online (Sandbox Code Playgroud) dithering ×10
android ×2
c ×2
gradient ×2
javascript ×2
matrix ×2
bitmap ×1
c# ×1
c++ ×1
canvas ×1
cielab ×1
colors ×1
gdi+ ×1
glsl ×1
octave ×1
php ×1
pixel-shader ×1
quantization ×1
surfaceview ×1