Image processing-semi-color fusion
In image processing, error propagation and jitter algorithms are used in digital semi-Tune Technology. They are newspaper, black, and white.
Printer and other output devices often use the technology. Common image semi-tuning techniques include Matrix Error spread, freuch-
Standberg error spread, space fill curve sampling error spread, etc. This article uses the semi-tuning algorithm to implement two
The fusion of images combines the background texture into the target image to create an amazing image processing effect.
Basic Idea of algorithms:
Read the pixel p (x, y) of the texture image and the corresponding pixel d (x, y) of the target image. input parameter adjustment s value range [0 ~ 1]
Calculate the color difference cs = S * 255 Based on the parameter S. Assume that the pixel values are p (x, y) = mV, d (x, y) = DV.
Then, the merged pixel value Pd (x, y) = 255 * (1-3x ^ 2-2x ^ 3) where x = (MV-(DV-CS)/2cs)
Running effect:
The background images are:
Program source code:
package com.gloomyfish.filter.study;import java.awt.image.BufferedImage;/** * A filter which uses a another image as a ask to produce a halftoning effect. */public class HalftoneFilter extends AbstractBufferedImageOp {private float softness = 0.1f;private boolean invert;private BufferedImage mask;public HalftoneFilter() {System.out.println("Stylize/Halftone...");}/** * Set the softness of the effect in the range 0..1. * @param softness the softness * @min-value 0 * @max-value 1 */public void setSoftness( float softness ) {this.softness = softness;}/** * Get the softness of the effect. * @return the softness * @see #setSoftness */public float getSoftness() {return softness;}/** * Set the halftone background image. * @param BufferedImage maskImage * @see #getMask */public void setMask( BufferedImage maskImage ) {this.mask = maskImage;}public void setInvert( boolean invert ) {this.invert = invert;} public BufferedImage filter( BufferedImage src, BufferedImage dst ) { int width = src.getWidth(); int height = src.getHeight(); if ( dst == null ) dst = createCompatibleDestImage( src, null );if ( mask == null )return dst; int maskWidth = mask.getWidth(); int maskHeight = mask.getHeight(); // scale to [0~255] float s = 255*softness; int[] inPixels = new int[width];int[] maskPixels = new int[maskWidth]; for ( int y = 0; y < height; y++ ) {getRGB( src, 0, y, width, 1, inPixels ); // get row pixelsgetRGB( mask, 0, y % maskHeight, maskWidth, 1, maskPixels ); // get row pixelsfor ( int x = 0; x < width; x++ ) {int maskRGB = maskPixels[x % maskWidth];int inRGB = inPixels[x];if ( invert ) maskRGB ^= 0xffffff;// start to halftone here!! int ir = (inRGB >> 16) & 0xff; int ig = (inRGB >> 8) & 0xff; int ib = inRGB & 0xff; int mr = (maskRGB >> 16) & 0xff; int mg = (maskRGB >> 8) & 0xff; int mb = maskRGB & 0xff; int r = (int)(255 * (1-cubeInterpolation( ir-s, ir+s, mr ))); int g = (int)(255 * (1-cubeInterpolation( ig-s, ig+s, mg ))); int b = (int)(255 * (1-cubeInterpolation( ib-s, ib+s, mb ))); inPixels[x] = (inRGB & 0xff000000) | (r << 16) | (g << 8) | b; }setRGB( dst, 0, y, width, 1, inPixels ); } return dst; } public static float cubeInterpolation(float a, float b, float x) {if (x < a)return 0;if (x >= b)return 1;x = (x - a) / (b - a);return x*x * (3 - 2*x);}}