Class ResampleOpSingleThread
java.lang.Object
com.mortennobel.imagescaling.AdvancedResizeOp
com.mortennobel.imagescaling.experimental.ResampleOpSingleThread
- All Implemented Interfaces:
BufferedImageOp
Based on work from Java Image Util ( http://schmidt.devlib.org/jiu/ )
Note that the filter method is not thread safe
-
Nested Class Summary
Nested ClassesNested classes/interfaces inherited from class com.mortennobel.imagescaling.AdvancedResizeOp
AdvancedResizeOp.UnsharpenMask
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate int
private int
private ResampleFilter
private final int
private int
private int
private int
private int
private int
-
Constructor Summary
ConstructorsConstructorDescriptionResampleOpSingleThread
(int destWidth, int destHeight) ResampleOpSingleThread
(DimensionConstrain dimensionConstrain) -
Method Summary
Modifier and TypeMethodDescriptioncreateSubSampling
(int srcSize, int dstSize) doFilter
(BufferedImage srcImg, BufferedImage dest, int dstWidth, int dstHeight) protected int
private void
getSamplesHorizontal
(byte[] src, int channel, int[] dest) private void
putSample
(byte[] image, int channel, float sample, int location) private void
scale
(BufferedImage srcImg, byte[][] workPixels, BufferedImage outImage) Pseudocode: for each for in destination image check that all dependent rows in source image is scaled horizontally and stored in work pixels if not then scale missing rows horizontal and store them in work pixels Scale the destination row vertically and store the result in out pixels It may seem counter intuitive that the vertical scale is done for each row.void
setFilter
(ResampleFilter filter) private void
setProgress
(int zeroBasedIndex, int totalItems) Methods inherited from class com.mortennobel.imagescaling.AdvancedResizeOp
addProgressListener, createCompatibleDestImage, filter, fireProgressChanged, getBounds2D, getPoint2D, getRenderingHints, getUnsharpenMask, removeProgressListener, setUnsharpenMask
-
Field Details
-
MAX_CHANNEL_VALUE
private final int MAX_CHANNEL_VALUE- See Also:
-
nrChannels
private int nrChannels -
srcWidth
private int srcWidth -
srcHeight
private int srcHeight -
dstWidth
private int dstWidth -
dstHeight
private int dstHeight -
horizontalSubsamplingData
-
verticalSubsamplingData
-
processedItems
private int processedItems -
totalItems
private int totalItems -
filter
-
-
Constructor Details
-
ResampleOpSingleThread
public ResampleOpSingleThread(int destWidth, int destHeight) -
ResampleOpSingleThread
-
-
Method Details
-
getFilter
-
setFilter
-
doFilter
public BufferedImage doFilter(BufferedImage srcImg, BufferedImage dest, int dstWidth, int dstHeight) - Specified by:
doFilter
in classAdvancedResizeOp
-
createSubSampling
-
scale
Pseudocode: for each for in destination image check that all dependent rows in source image is scaled horizontally and stored in work pixels if not then scale missing rows horizontal and store them in work pixels Scale the destination row vertically and store the result in out pixels It may seem counter intuitive that the vertical scale is done for each row. The simple scaling algorithm would first scale the image horizontal (a row at a time) into the temp image, and then scale the temp image vertically (a column at a time) into the final image. The disadvantage of the simple approach is that you need a large temporary image. I have avoided this by doing the vertically scale a row at a time. Scaling a single row vertically, needs the horizontally scaled rows that the scaling depends on. These dependencies will be lazy initialized. Since we know the height of the 'window' we work on (the maximum number of source rows needed to calculate a dest row), the work pixels only needs to have the same height. Instead of creating a temporary image with a height different from the source image's height, I created a double array where inner array is repeated (so if the window height is 3 the first and the forth row is the same instance). This keeps algorithm a bit simpler (the alternative would be to maintain a mapping between)- Parameters:
srcImg
- source imageworkPixels
- temporary imageoutImage
- result image
-
putSample
private void putSample(byte[] image, int channel, float sample, int location) -
getSamplesHorizontal
private void getSamplesHorizontal(byte[] src, int channel, int[] dest) -
setProgress
private void setProgress(int zeroBasedIndex, int totalItems) -
getResultBufferedImageType
-