Some of the digital image processing issues were exposed to some of the brothers, and some basic 2D image processing algorithms were completed under the J2ME platform. It is a summary of this knowledge to decide to write these algorithms, and discuss together with friends. This article first introduces the implementation of image amplification reduction, and the program is implemented as a platform for NOKIA S40. 1. Implementing the basic idea of graphic scaling: the transformation of the image is simple to say that the source image each point coordinate is converted to a new coordinate corresponding to the target image corresponding to the target image, but this will result in a problem that the coordinate of the target point is usually Will not be an integer. So when we do amplifying, we need to calculate the point where the generated is not mapped; and there is a need to delete some points when narrowing the transformation. Here we use the simplest interpolation algorithm: "Recent neighborhood law". As the name suggests, the non-integer coordinate is a four-bedroom, take the most recent integer point. Look at one picture of the following picture, the left picture is the original image, the right picture is an image of 1 times. The number inside, indicating the information of the pixel
2. For the operation of the image pixel: Get image picture pixel information: Standard MIDP 1.0 does not provide functions for obtaining image pixel information, for NOKIA machine, we can use the API provided by Nokia SDK to get pixel information. Specific procedures are as follows: g = image.getGraphics () DirectGraphics dg = DirectUtils.getDirectGraphics (g); dg.getPixels (short [] pixels, int offset, int scanlength, int x, int y, int width, int height, int format Parameter introduction: short [] Pixels: An array INT Offset for receiving pixel information: The place in this article, add 0, Int Scanlength: Add the width INT x: Add 0INT Y: Add 0int Width: Picture Width INT Height: Picture Height INT FORMAT: 444, indicating a graphic format, as if the NOKIA S40 machine is used to represent the RGB color in 444 format. It is red, green, and blue each represents 4 bits, so that it can represent the 4444 format of transparent color Argb, which should be implemented by machine hardware. If you want to know the information of NOKIA SDK, you can view the help documentation of the Nokia SDK.
Generating an array of pixel information using Image Image: image = Image.createImage (w, h); g = image.getGraphics () DirectGraphics dg = DirectUtils.getDirectGraphics (g); dg.drawPixels (short [] pixels, boolean transparency, int offset , int Scanlength, Int X, INT Y, INT Width, Int Height, Int manipulation, int format, INT [] Pixels: Pixel information array boolean transparency: Whether to include Alpha bit information int off version: Add 0int Scanlength: Add a picture to the width INT x: Add 0INT Y: Add 0int Width: Picture Width INT Height: Picture Height Int Manipulation: Add 0int Format: 444
The specific algorithm begins below, first give the full function of the image zoom, then explain the code, segment / *********************** ******** * @todo picture zoom in zoom in * @Param srcimg Original image * @Param desw After changing image width * @Param DESH changing image high * @return processed picture ***** ********************************************** / Private Image ZoomImage (Image srcimg, Int desw, int desh) {int srcw = srcimg.GetWidth ); // raw image wide int srch = srcimg.getHeight (); // Original image high short [] srcbuf = new short [srcw * srch]; // Original image pixel information cache
// srcbuf acquisition image pixel information image design; image.createImage (srcw, srch); if (srcimg.ismutable ()) {/ * If it is a variable image * / Directutils.getDirectGraphics ()). getpixels ( Srcbuf, 0, SRCW, 0, 0, SRCW, SRCH, 444);} else {/ * If it is a non-variable image * / desimg.getgraphics (). DrawImage (srcimg, 0, 0, 0); DirectUtils.getdirectGraphics Desimg.getgraphics ()). Getpixels (srcbuf, 0, srcw, 0, 0, srcw, srch, 444);
// Calculate Interpolation Table Short [] Taby = New Short [DESH]; short [] Tabx = New Short [desw];
INT SB = 0; int TEMD = 0; int TEMD = 0; int Distance = SRCH> DESH? SRCH: DESH; For (int i = 0; i <= distance; i ) {/ * vertical direction * / Taby [DB] = (short) SB; TEMS = SRCH; TEMD = DESH; if (Tems> Distance) {TEMS - = Distance; Sb ;} if (TEMD> DISTANCE) {TEMD - = distance; DB }}
SB = 0; db = 0; TEMS = 0; TEMD = 0; DISTANCE = SRCW> DESW? SRCW: DESW; for (int i = 0; i <= distance; i ) {/ * Level direction * / TABX [DB ] = (short) SB; TEMS = SRCW; TEMD = desw; if (Tems> Distance) {TEMS - = Distance; Sb ;} IF (TEMD> DISTANCE) {TEMD - = distance; DB ;}} // Generate an enlarged reduction post [] desbuf = new short [desw * desh]; int Dx = 0; int Dy = 0; int SX = 0; int Sy = 0; int = -1; for (INT i = 0; i // Generate picture desimg = image.createImage (DESW, DESH); Directutils.getdirectGraphics (Desimg.getgraphics ()). Drawpixels (Desbuf, True, 0, DESW, 0, 0, DESW, DESH, 0, 444); Return DESIMG; First, see the first two sentences of the function, it is easy to get the width and height of the original picture and the height INT SRCW = srcimg.GetWidth (); // Original image wide int srch = srcimg.getHeight (); // The original image is connected to a sentence We want to define a short type, as a cache for the original image pixel information, short [] srcbuf = new short [srcw * srch]; Again, some friends may have some unclear, here to explain it. Due to getPixels () this function, only the pixel information of the variable image, the non-variable image, and the pixel information cannot be acquired. So we want to use srcimg.ismutable () to determine, the original image is not a variable image, then divided into two cases. If srcimg is a variable image, we use GetPixels () to get its pixel information and save it in srcbuf. If srcimg is not a variable image, we need to draw SRCIMAGE on the prior variable image Desimg, and then get the pixel information of Desimg. Image desimg = image.createImage (srcw, srch); if (srcimg.ismutable ()) {/ * If it is a variable image * / DirectUTILS.GETDIRECTGRAPHICS (Srcimg.getgraphs ()). Getpixels (srcbuf, 0, srcw, 0 , 0, SRCW, SRCH, 444);} else {/ * If it is a non-variable image * / desimg.getgraphics (). DrawImage (srcimg, 0, 0, 0); DirectUtils.getdirectGraphics (Desimg.GRAPHICS ()). GetPixels (srcbuf, 0, srcw, 0, 0, srcw, srch, 444);} The next is the focus of the zoom algorithm: the generation of the interpolated table. Interpolated Table Solution Horizontal Difference Table and Vertical Interpolation Table, we must generate two interpolation tables of the original image matrix, then use the interpolation table to generate an image matrix after zooming. Since this content is more abstract, it is difficult to use text expression, so we introduce in an example. Let's see the top 1 * 4 form below ----------------- | 0 | 1 | 2 | ------------- ---- If you want to enlarge this form into 1 * 6 table, the zoomed table has 2 lattice than the original form, and we can only interpolate this more 2 lattices to complete the enlarged operation. This process is now completed in conjunction with the code to generate a horizontal interpolated table. Distance = srcw> desw? srcw: desw; for (int i = 0; i <= distance; i ) {/ * horizontal direction * / tabx [db] = (short) SB; TEMS = srcw; TEMD = DESW ; If (Tems> Distance) {TEMS - = Distance; SB ;}}}}}} {TEMD - = Distance; DB ;}} Obviously, the original table width SRCW = 4; the zoom table width DESW = 6; so distance = desw = 6 Next to enter the for loop, our steps to calculate the process of its loop --------- -------------------------------------- | I | TABX assignment operation | TEMS | TEMD | SB | DB | ----------------------------------------------- | 0 Tabx [0] = 0 | 4 | 6 | 0 | 0 | ---------------------------------- ------------- | 1 | Tabx [0] = 0 | 2 | 6 | 1 | 1 | ------------------- ---------------------------- | 2 | Tabx [0] = 1 | 6 | 6 | 1 | 2 | ------------------------------------------- | 3 | Tabx [0] = 1 | 4 | 6 | 2 | 3 | ------------------------------------- -------- | 4 | TabX [0] = 2 | 2 | 6 | 3 | 4 | ------------------------ ----------------------- | 5 | TabX [0] = 3 | 6 | 6 | 3 | 5 | --------- -------------------------------------- | 6 | TabX [0] = 3 | 4 | 6 | 4 | 6 | ------------------------------------------ --- Thereby giving the form that enlarges 1 * 6 is shown below. The number n in each of each cell represents the content of this cell, as the contents of the nth cell in the original table. -------------------------- | 0 | 1 | 1 | 2 | 3 | 3 | ----------- --------------- For example, the left picture is the original form, the right picture is the form of enlarged --------------------- -------------------------------- | Red | Green | Lan | Purple | | Red | Green | Green | Lan |紫 | 紫 | ----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------- With 2 interpolation tables, the image after zooming and narrowing can be generated below. Short [] desbuf = new short [desw * desh]; int DX = 0; int Dy = 0; int SX = 0; int Sy = 0; int = -1; for (int i = 0; i } else {/ ********** The situation two ********** / dx = 0; for (int J = 0; J Desbuf is used to save image data after zooming in zooming. For example, we amplify a 4 * 4-pixel image A into 6 * 6 image B. We can generate two interpolated tables according to the previous introduction. Tabx = {0, 1, 1, 2, 3, 3}, Taby = {0, 1, 1, 2, 3, 3}. It is judged whether or not Oldy is equal to TABY [I] in the cycle, this operation is equal to whether Taby [i-1] is equal to TABY [I]. If equals, the data that has been generated in front of the image B and the same line data to be generated, as long as System.ArrayCopy (Desbuf, DY - DESW, DESBUF, DY, DESW) copys the data from the previous line, Can; if it is not equal, you need to generate the data of this line to the horizontal interpolation table Tabx. The algorithm demo is as follows: ---------------------------- | I | Oldy | TABY [I] | Arcade | ---- ------------------------ | 0 | -1 | 0 | Case 2 | --------------- ------------- | 1 | 0 | 1 | Case 2 | --------------------------- - | 2 | 1 | 1 | Address 1 | ---------------------------- | 3 | 1 | 2 | --------------------------- | 4 | 2 | 3 | Case 2 | ------------- --------------- | 5 | 3 | 3 | Situation 1 | ------------------------- --- Then we use Desbuf to generate events that ultimately zoom in to zoom in or narrowed Desimg = Image.createImage (Directutils.getdirectGraphics (Desimg.getgraphDirectGraphics). Drawpixels (Desbuf, True, 0, Desw, 0, 0 , DESW, DESH, 0, 444; RETURN Desimg; Below is the effect of this algorithm to enhance the zoom Finally, it is to be explained that because image.createImage (W, h) is used in this algorithm to create an image, this function creates a full-white variable image of the W * H pixel, so the transparent picture is zoomed out, the background is not Reprimight, but white, this is the lack of J2ME itself and the algorithm. For this problem, there is a solution that is the picture of the program does not use image to save, but use the short [] array to save, the drawing is drawn with Drawpixels ().