I have a implemented a ListField on BlackBerry. How do I add 3 labels to the list?
Follow this tutorial:
http://berrytutorials.blogspot.com/2009/11/create-custom-listfield-change.html
After completed, modify the extended ListField class by adding some extra components to your list (graphics.drawText(CALLBACK OBJECT, X, Y)). Change the String callback to an object of your type(or just an Array) with the availability for more elements.
EXAMPLE OF THE PAINT METHOD INSIDE THE EXTENDED LISTFIELD CLASS:
public void paint(Graphics graphics) {
int width = (int) (300 * resizeWidthFactor);
// Get the current clipping region
XYRect redrawRect = graphics.getClippingRect();
// Side lines
// graphics.setColor(Color.GRAY);
// graphics.drawLine(0, 0, 0, redrawRect.height);
// graphics.setColor(Color.GRAY);
// graphics.drawLine(redrawRect.width-1, 0, redrawRect.width-1,
// redrawRect.height);
if (redrawRect.y < 0) {
throw new IllegalStateException("Error with clipping rect.");
}
// Determine the start location of the clipping region and end.
int rowHeight = getRowHeight();
int curSelected;
// If the ListeField has focus determine the selected row.
if (hasFocus) {
curSelected = getSelectedIndex();
} else {
curSelected = -1;
}
int startLine = redrawRect.y / rowHeight;
int endLine = (redrawRect.y + redrawRect.height - 1) / rowHeight;
endLine = Math.min(endLine, getSize() - 1);
int y = (startLine * rowHeight) + heightMargin;
// Setup the data used for drawing.
int[] yInds = new int[] { y, y, y + rowHeight, y + rowHeight };
int[] xInds = new int[] { 0, width, width, 0 };
// Set the callback - assuming String values.
ListFieldCallback callBack = this.getCallback();
// Draw each row
for (; startLine <= endLine; ++startLine) {
// If the line we're drawing is the currentlySelected line then draw the
// fill path in LIGHTYELLOW and the
// font text in Black.
//OBJECT OF OWN TYPE FOR MULTIPLE PARAMETERS
ProductDetails data = (ProductDetails) callBack.get(this, startLine);
String productDescription = "";
String errorDescription = "";
if (data.isError()) {
errorDescription = TextLineSplitter.wrapString1Line(data.getErrorMessage(), (int) ((300 - (2 * widthMargin)) * resizeWidthFactor), getFont());
} else {
productDescription = TextLineSplitter.wrapString1Line(data.getProductDesc(), (int) ((300 - (2 * widthMargin)) * resizeWidthFactor), getFont());
}
// Set differences by row (selected or not)
if (startLine == curSelected) {
graphics.setColor(Color.WHITE);
} else {
// Draw the odd or selected rows.
graphics.setColor(Color.BLACK);
}
// Set text values
if (!data.isError()) {
// If no error found
//FIRST LABEL
graphics.setFont(getFont().derive(Font.BOLD));
graphics.drawText("Result search " + Integer.toString(data.getSearchId()) + ":", widthMargin, yInds[0]);
graphics.drawText(data.getManufacturerItemIdentifier(), widthMargin + (int) (140 * resizeWidthFactor), yInds[0]);
//SECOND LABEL
graphics.setFont(getFont().derive(Font.PLAIN));
graphics.drawText(productDescription, widthMargin, yInds[0] + (int) (20 * resizeHeightFactor));
} else {
// Error found
graphics.setColor(Color.GRAY);
graphics.setFont(getFont().derive(Font.BOLD));
graphics.drawText("Result search " + Integer.toString(data.getSearchId()) + ":", widthMargin, yInds[0]);
graphics.setFont(getFont().derive(Font.PLAIN));
graphics.drawText(errorDescription, widthMargin, yInds[0] + (int) (20 * resizeHeightFactor));
}
// Bottom line
if (startLine == endLine) {
graphics.setColor(Color.GRAY);
graphics.drawLine(0, yInds[2] - (heightMargin + 1), (int) (300 * resizeWidthFactor), yInds[2] - (heightMargin + 1));
}
// Horizontal lines
graphics.setColor(Color.GRAY);
graphics.drawLine(0, yInds[0] - heightMargin, (int) (300 * resizeWidthFactor), yInds[0] - heightMargin);
// Assign new values to the y axis moving one row down.
y += rowHeight;
yInds[0] = y;
yInds[1] = yInds[0];
yInds[2] = y + rowHeight;
yInds[3] = yInds[2];
}
// super.paint(graphics);
}
Related
How can I calculate distance between a fixed parameter and a target image/pixel?
The following code does color recognition, finds the average position, and draws circle on it. It is able to find if the target (averageX and averageY) is close to leftPd, centerPd, or rightPd. I want to change this code as lane tracking which is at least able to find distance value between leftPd parameter variable and left lane or rightPd parameter variable and right lane.
import processing.video.*;
Capture video;
float threshold = 210;
color trackColor;
PVector leftP, centerP, rightP, target;
void setup() {
leftP = new PVector (80,420);
centerP = new PVector (width/2, 380);
rightP = new PVector (560,420);
size(640, 480);
video = new Capture(this, width, height);
video.start();
trackColor = color(160,0,0); // Start off tracking for red
}
void captureEvent(Capture video) {
// Read image from the camera
video.read();
}
void draw() {
loadPixels();
video.loadPixels();
image(video, 0, 0);
float avgX = 0;
float avgY = 0;
int count = 0;
for (int x = 0; x < video.width; x ++ ) {
for (int y = 0; y < video.height; y ++ ) {
int loc = x + y*video.width;
color currentColor = video.pixels[loc];
float r1 = red(currentColor);
float g1 = green(currentColor);
float b1 = blue(currentColor);
float r2 = red(trackColor);
float g2 = green(trackColor);
float b2 = blue(trackColor);
// Using euclidean distance to compare colors
float d = distSq(r1, g1, b1, r2, g2, b2);
if (d < threshold) {
stroke(255);
strokeWeight(1);
point(x,y);
avgX += x;
avgY += y;
count++;
}
}
}
if (count > 0) {
avgX = avgX / count;
avgY = avgY / count;
// Draw a circle at the tracked pixel
fill(trackColor);
strokeWeight(4.0);
stroke(0);
ellipse(avgX, avgY, 20, 20);
text("brightnesslevel: " + trackColor, 20, 60);
text("FPS: " + frameRate, 20, 80);
}
target = new PVector (avgX, avgY);
color c = color(255, 204, 0);
fill(c);
noStroke();
ellipse(leftP.x,leftP.y,16,16); // left param
ellipse(centerP.x,centerP.y,16,16); // center param
ellipse(rightP.x,rightP.y,16,16); // right param
float leftPd = leftP.dist(target);
float centerPd = centerP.dist(target);
float rightPd = rightP.dist(target);
if ( leftPd <= 85 ){
text("To Close left " , 20, 250);
}
if ( centerPd <= 85 ){
text("To Close turn center " , 20, 275);
}
if ( rightPd <= 85 ){
text("To Close turn right " , 20, 300);
}
}
float distSq(float x1,float y1, float z1, float x2, float y2, float z2){
float d = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1);
return d;
}
void mousePressed() {
// Save color where the mouse is clicked in trackColor variable
int loc = mouseX + mouseY*video.width;
trackColor = video.pixels[loc];
}
I have two images with similar sizes that show similar scenes. How can we show two images in two frames and when panning or zooming in the left image, it pans and zooms in the right one? I don't want to concatenate the images though.
Is there a solution to do this? Both python or c++ OpenCV are fine.
About zoom in/out:
The basic idea is deciding the scale changed every time on mouse wheel. After you get the current scale (v.s. origin image) and correct region of image you want to show on screen, you can get the position and length of rectangle on scaled image. So you can draw this rectangle on scaled image.
In my github,checking OnMouseWheel () and RefreshSrcView () in Fastest_Image_Pattern_Matching/ELCVMatchTool/ELCVMatchToolDlg.cpp may give what you want.
About showing two images simutaneouly with same region:
use two picture boxes with MFC framework or other UI builder.
or use two cv::namedWindow () without framework
Effect:
Part of the code:
BOOL CELCVMatchToolDlg::OnMouseWheel (UINT nFlags, short zDelta, CPoint pt)
{
POINT pointCursor;
GetCursorPos (&pointCursor);
ScreenToClient (&pointCursor);
// TODO: 在此加入您的訊息處理常式程式碼和 (或) 呼叫預設值
if (zDelta > 0)
{
if (m_iScaleTimes == MAX_SCALE_TIMES)
return TRUE;
else
m_iScaleTimes++;
}
if (zDelta < 0)
{
if (m_iScaleTimes == MIN_SCALE_TIMES)
return TRUE;
else
m_iScaleTimes--;
}
CRect rect;
//GetWindowRect (rect);
GetDlgItem (IDC_STATIC_SRC_VIEW)->GetWindowRect (rect);//重要
if (m_iScaleTimes == 0)
g_dCompensationX = g_dCompensationY = 0;
int iMouseOffsetX = pt.x - (rect.left + 1);
int iMouseOffsetY = pt.y - (rect.top + 1);
double dPixelX = (m_hScrollBar.GetScrollPos () + iMouseOffsetX + g_dCompensationX) / m_dNewScale;
double dPixelY = (m_vScrollBar.GetScrollPos () + iMouseOffsetY + g_dCompensationY) / m_dNewScale;
m_dNewScale = m_dSrcScale * pow (SCALE_RATIO, m_iScaleTimes);
if (m_iScaleTimes != 0)
{
int iWidth = m_matSrc.cols;
int iHeight = m_matSrc.rows;
m_hScrollBar.SetScrollRange (0, int (m_dNewScale * iWidth - m_dSrcScale * iWidth) - 1 + BAR_SIZE);
m_vScrollBar.SetScrollRange (0, int (m_dNewScale * iHeight - m_dSrcScale * iHeight) - 1 + BAR_SIZE);
int iBarPosX = int (dPixelX * m_dNewScale - iMouseOffsetX + 0.5);
m_hScrollBar.SetScrollPos (iBarPosX);
m_hScrollBar.ShowWindow (SW_SHOW);
g_dCompensationX = -iBarPosX + (dPixelX * m_dNewScale - iMouseOffsetX);
int iBarPosY = int (dPixelY * m_dNewScale - iMouseOffsetY + 0.5);
m_vScrollBar.SetScrollPos (iBarPosY);
m_vScrollBar.ShowWindow (SW_SHOW);
g_dCompensationY = -iBarPosY + (dPixelY * m_dNewScale - iMouseOffsetY);
//滑塊大小
SCROLLINFO infoH;
infoH.cbSize = sizeof (SCROLLINFO);
infoH.fMask = SIF_PAGE;
infoH.nPage = BAR_SIZE;
m_hScrollBar.SetScrollInfo (&infoH);
SCROLLINFO infoV;
infoV.cbSize = sizeof (SCROLLINFO);
infoV.fMask = SIF_PAGE;
infoV.nPage = BAR_SIZE;
m_vScrollBar.SetScrollInfo (&infoV);
//滑塊大小
}
else
{
m_hScrollBar.SetScrollPos (0);
m_hScrollBar.ShowWindow (SW_HIDE);
m_vScrollBar.SetScrollPos (0);
m_vScrollBar.ShowWindow (SW_HIDE);
}
RefreshSrcView ();
return CDialogEx::OnMouseWheel (nFlags, zDelta, pt);
}
Output
I think the following code isn't giving the correct result.
What's wrong withe following code?
public class ImagePadder
{
public static Bitmap Pad(Bitmap image, int newWidth, int newHeight)
{
int width = image.Width;
int height = image.Height;
if (width >= newWidth) throw new Exception("New width must be larger than the old width");
if (height >= newHeight) throw new Exception("New height must be larger than the old height");
Bitmap paddedImage = Grayscale.CreateGrayscaleImage(newWidth, newHeight);
BitmapLocker inputImageLocker = new BitmapLocker(image);
BitmapLocker paddedImageLocker = new BitmapLocker(paddedImage);
inputImageLocker.Lock();
paddedImageLocker.Lock();
//Reading row by row
for (int y = 0; y < image.Height; y++)
{
for (int x = 0; x < image.Width; x++)
{
Color col = inputImageLocker.GetPixel(x, y);
paddedImageLocker.SetPixel(x, y, col);
}
}
string str = string.Empty;
paddedImageLocker.Unlock();
inputImageLocker.Unlock();
return paddedImage;
}
}
Relevant Source Code:
public class BitmapLocker : IDisposable
{
//private properties
Bitmap _bitmap = null;
BitmapData _bitmapData = null;
private byte[] _imageData = null;
//public properties
public bool IsLocked { get; set; }
public IntPtr IntegerPointer { get; private set; }
public int Width { get { return _bitmap.Width; } }
public int Height { get { return _bitmap.Height; } }
public int Stride { get { return _bitmapData.Stride; } }
public int ColorDepth { get { return Bitmap.GetPixelFormatSize(_bitmap.PixelFormat); } }
public int Channels { get { return ColorDepth / 8; } }
public int PaddingOffset { get { return _bitmapData.Stride - (_bitmap.Width * Channels); } }
public PixelFormat ImagePixelFormat { get { return _bitmap.PixelFormat; } }
public bool IsGrayscale { get { return Grayscale.IsGrayscale(_bitmap); } }
//Constructor
public BitmapLocker(Bitmap source)
{
IsLocked = false;
IntegerPointer = IntPtr.Zero;
this._bitmap = source;
}
/// Lock bitmap
public void Lock()
{
if (IsLocked == false)
{
try
{
// Lock bitmap (so that no movement of data by .NET framework) and return bitmap data
_bitmapData = _bitmap.LockBits(
new Rectangle(0, 0, _bitmap.Width, _bitmap.Height),
ImageLockMode.ReadWrite,
_bitmap.PixelFormat);
// Create byte array to copy pixel values
int noOfBitsNeededForStorage = _bitmapData.Stride * _bitmapData.Height;
int noOfBytesNeededForStorage = noOfBitsNeededForStorage / 8;
_imageData = new byte[noOfBytesNeededForStorage * ColorDepth];//# of bytes needed for storage
IntegerPointer = _bitmapData.Scan0;
// Copy data from IntegerPointer to _imageData
Marshal.Copy(IntegerPointer, _imageData, 0, _imageData.Length);
IsLocked = true;
}
catch (Exception)
{
throw;
}
}
else
{
throw new Exception("Bitmap is already locked.");
}
}
/// Unlock bitmap
public void Unlock()
{
if (IsLocked == true)
{
try
{
// Copy data from _imageData to IntegerPointer
Marshal.Copy(_imageData, 0, IntegerPointer, _imageData.Length);
// Unlock bitmap data
_bitmap.UnlockBits(_bitmapData);
IsLocked = false;
}
catch (Exception)
{
throw;
}
}
else
{
throw new Exception("Bitmap is not locked.");
}
}
public Color GetPixel(int x, int y)
{
Color clr = Color.Empty;
// Get color components count
int cCount = ColorDepth / 8;
// Get start index of the specified pixel
int i = (Height - y - 1) * Stride + x * cCount;
int dataLength = _imageData.Length - cCount;
if (i > dataLength)
{
throw new IndexOutOfRangeException();
}
if (ColorDepth == 32) // For 32 bpp get Red, Green, Blue and Alpha
{
byte b = _imageData[i];
byte g = _imageData[i + 1];
byte r = _imageData[i + 2];
byte a = _imageData[i + 3]; // a
clr = Color.FromArgb(a, r, g, b);
}
if (ColorDepth == 24) // For 24 bpp get Red, Green and Blue
{
byte b = _imageData[i];
byte g = _imageData[i + 1];
byte r = _imageData[i + 2];
clr = Color.FromArgb(r, g, b);
}
if (ColorDepth == 8)
// For 8 bpp get color value (Red, Green and Blue values are the same)
{
byte c = _imageData[i];
clr = Color.FromArgb(c, c, c);
}
return clr;
}
public void SetPixel(int x, int y, Color color)
{
// Get color components count
int cCount = ColorDepth / 8;
// Get start index of the specified pixel
int i = (Height - y - 1) * Stride + x * cCount;
try
{
if (ColorDepth == 32) // For 32 bpp set Red, Green, Blue and Alpha
{
_imageData[i] = color.B;
_imageData[i + 1] = color.G;
_imageData[i + 2] = color.R;
_imageData[i + 3] = color.A;
}
if (ColorDepth == 24) // For 24 bpp set Red, Green and Blue
{
_imageData[i] = color.B;
_imageData[i + 1] = color.G;
_imageData[i + 2] = color.R;
}
if (ColorDepth == 8)
// For 8 bpp set color value (Red, Green and Blue values are the same)
{
_imageData[i] = color.B;
}
}
catch (Exception ex)
{
throw new Exception("(" + x + ", " + y + "), " + _imageData.Length + ", " + ex.Message + ", i=" + i);
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// free managed resources
_bitmap = null;
_bitmapData = null;
_imageData = null;
IntegerPointer = IntPtr.Zero;
}
}
}
The layout of a Windows bitmap is different than you might expect. The bottom line of the image is the first line in memory, and continues backwards from there. It can also be laid out the other way when the height is negative, but those aren't often encountered.
Your calculation of an offset into the bitmap appears to take that into account, so your problem must be more subtle.
int i = (Height - y - 1) * Stride + x * cCount;
The problem is that the BitmapData class already takes this into account and tries to fix it for you. The bitmap I described above is a bottom-up bitmap. From the documentation for BitmapData.Stride:
The stride is the width of a single row of pixels (a scan line), rounded up to a four-byte boundary. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up.
It is intended to be used with the Scan0 property to access the bitmap in a consistent fashion whether it's top-down or bottom-up.
I am codeing a little project where i need a Line from a given Object to my Mouse. I made things work and came up with this quick and dirty code:
addListener(new ClickListener() {
Image lineImage;
Pixmap pixmap;
#Override
public void touchDragged(InputEvent event, float x, float y, int pointer) {
// Get Actor Origin
// Get local Origin
int x2 = (int) event.getListenerActor().getX(Align.center);
int y2 = (int) event.getListenerActor().getY(Align.center);
// Make it global
x2 = (int) event.getListenerActor().getParent().getX() + x2;
y2 = (int) event.getListenerActor().getParent().getY() + y2;
// Get Stage Coordinates
Vector2 v = localToStageCoordinates(new Vector2(x, y));
Vector2 v2 = new Vector2(x2, y2);
Stage stage = event.getStage();
int width = (int) stage.getWidth();
int height = (int) stage.getHeight();
if (pixmap == null) {
pixmap = new Pixmap(width, height, Pixmap.Format.RGBA8888);
} else {
pixmap.setColor(1, 1, 1, 0);
pixmap.fill();
}
pixmap.setColor(Color.BLUE);
// line
for (int m = -2; m <= 2; m++) {// x
for (int n = -2; n <= 2; n++) {// y
pixmap.drawLine((int) (v2.x+m), (int) (height-v2.y+n) , (int) (v.x+m), (int) (height-v.y+n));
}
}
if (lineImage != null) {
/*lineImage.clear();
lineImage.remove();
*/
lineImage.setDrawable(new SpriteDrawable(new Sprite(new Texture(pixmap))));
} else {
lineImage = new Image(new Texture(pixmap));
}
lineImage.setPosition(0,0);
stage.addActor(lineImage);
// super.touchDragged(event, x, y, pointer);
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
if (lineImage != null) {
lineImage.clear();
lineImage.remove();
}
lineImage = null;
super.touchUp(event, x, y, pointer, button);
}
});
The Problem with this is, when i use this Listener on a Image and i activate touchdragged for about 20 seconds, there will be a memory leak.
I have no idea why this happens, i tried a lot of things but nothing seams to help me fix this. Do you have any ideas?
#noone is right. Add the line where is commented to dispose your pixmap after you assigned the drawable to the lineImage.
if (lineImage != null) {
/*lineImage.clear();
lineImage.remove();
*/
lineImage.setDrawable(new SpriteDrawable(new Sprite(new Texture(pixmap))));
} else {
lineImage = new Image(new Texture(pixmap));
}
pixmap.dispose(); // <-----------Add this line here!!!
lineImage.setPosition(0,0);
stage.addActor(lineImage);
For my current code, it will download the images first then only display data and cause the device like lagging.
public Custom_ListField(Vector content, boolean islatest) {
this.content = content;
this.islatest = islatest;
newsid = new int[content.size()];
title = new String[content.size()];
category = new String[content.size()];
date = new String[content.size()];
imagepath = new String[content.size()];
catsid = new int[content.size()];
imagebitmap = new Bitmap[content.size()];
ischeck = new boolean[content.size()];
for (int i = 0; i < content.size(); i++) {
newslist = (List_News) content.elementAt(i);
newsid[i] = newslist.getID();
title[i] = newslist.getNtitle();
category[i] = newslist.getNewCatName();
date[i] = newslist.getNArticalD();
imagepath[i] = newslist.getImagePath();
catsid[i] = newslist.getCatID();
ischeck[i] = false;
if (!imagepath[i].toString().equals("no picture")) {
if (Config_GlobalFunction.isConnected())
imagebitmap[i] = Util_ImageLoader.loadImage(imagepath[i]);
else
imagebitmap[i] = localimage;
}
}
initCallbackListening();
}
private void initCallbackListening() {
callback = new ListCallback();
this.setCallback(callback);
this.setRowHeight(-2);
}
private class ListCallback implements ListFieldCallback {
public ListCallback() {
}
public void drawListRow(ListField listField, Graphics graphics,
final int index, int y, int width) {
currentPosition = index;
if (!imagepath[index].toString().equals("no picture")) {
float ratio = (float) ((float) localimage.getHeight() / (float) imagebitmap[index]
.getHeight());
Bitmap temp = new Bitmap(
(int) (imagebitmap[index].getWidth() * ratio),
(int) (imagebitmap[index].getHeight() * ratio));
imagebitmap[index].scaleInto(temp, Bitmap.FILTER_BILINEAR,
Bitmap.SCALE_TO_FIT);
imagebitmap[index] = temp;
graphics.drawBitmap(
Display.getWidth()
- localimage.getWidth()
- 5
+ ((localimage.getWidth() - imagebitmap[index]
.getWidth()) / 2),
y
+ (listField.getRowHeight(index) - imagebitmap[index]
.getHeight()) / 2,
imagebitmap[index].getWidth(),
imagebitmap[index].getHeight(), imagebitmap[index], 0,
0);
graphics.setColor(Color.BLACK);
text = Config_GlobalFunction
.wrap(title[index], Display.getWidth()
- imagebitmap[index].getWidth() - 15);
for (int i = 0; i < text.size(); i++) {
int liney = y + (i * Font.getDefault().getHeight());
graphics.drawText(
(String) text.elementAt(i),
5,
liney + 3,
DrawStyle.TOP | DrawStyle.LEFT | DrawStyle.ELLIPSIS,
Display.getWidth() - imagebitmap[index].getWidth()
- 10);
}
} else {
graphics.setColor(Color.BLACK);
text = Config_GlobalFunction.wrap(title[index],
Display.getWidth() - 10);
for (int i = 0; i < text.size(); i++) {
int liney = y + (i * Font.getDefault().getHeight());
graphics.drawText(
(String) text.elementAt(i),
5,
liney + 3,
DrawStyle.TOP | DrawStyle.LEFT | DrawStyle.ELLIPSIS,
Display.getWidth() - 10);
}
}
if (text.size() == 2) {
graphics.setColor(Color.GRAY);
graphics.drawText(date[index], 5, y
+ Font.getDefault().getHeight() + 3);
if (islatest) {
graphics.setColor(Color.RED);
graphics.drawText(category[index], Font.getDefault()
.getAdvance(date[index]) + 15, y
+ Font.getDefault().getHeight() + 3);
}
} else if (text.size() == 3) {
graphics.setColor(Color.GRAY);
graphics.drawText(date[index], 5, y
+ Font.getDefault().getHeight() * 2 + 3);
if (islatest) {
graphics.setColor(Color.RED);
graphics.drawText(category[index], Font.getDefault()
.getAdvance(date[index]) + 15, y
+ Font.getDefault().getHeight() * 2 + 3);
}
}
if (!imagepath[index].toString().equals("no picture"))
setRowHeight(index, imagebitmap[index].getHeight() + 10);
else {
if (text.size() == 2)
setRowHeight(index, getRowHeight() + 9);
else if (text.size() == 3) {
setRowHeight(index, getRowHeight() * 15 / 10 + 9);
}
}
graphics.setColor(Color.WHITE);
graphics.drawRect(0, y, width, listField.getRowHeight(index));
ischeck[index] = true;
}
}
I want this imagebitmap[i] = Util_ImageLoader.loadImage(imagepath[i]); run after display data so that no need stuck there. However, I tried to put inside drawListRow, it works but very slow because initially display it will run 0-8 times then when i scroll the listfield, it run again. It was download and download again.
Update
public class Util_LazyLoader implements Runnable {
String url = null;
BitmapDowloadListener listener = null;
public Util_LazyLoader(String url, BitmapDowloadListener listener) {
this.url = url;
this.listener = listener;
}
public void run() {
Bitmap bmpImage = getImageFromWeb(url);
listener.ImageDownloadCompleted(bmpImage);
}
private Bitmap getImageFromWeb(String url) {
HttpConnection connection = null;
InputStream inputStream = null;
EncodedImage bitmap;
byte[] dataArray = null;
try {
connection = (HttpConnection) (new ConnectionFactory())
.getConnection(url + Database_Webservice.ht_params)
.getConnection();
int responseCode = connection.getResponseCode();
if (responseCode == HttpConnection.HTTP_OK) {
inputStream = connection.openDataInputStream();
dataArray = IOUtilities.streamToBytes(inputStream);
}
} catch (Exception ex) {
} finally {
try {
inputStream.close();
connection.close();
} catch (Exception e) {
}
}
if (dataArray != null) {
bitmap = EncodedImage.createEncodedImage(dataArray, 0,
dataArray.length);
return bitmap.getBitmap();
} else {
return null;
}
}
}
I created a new class but i don't know how to use it.
You need to use lazy loading concept here.
For ex:
http://supportforums.blackberry.com/t5/Java-Development/How-to-load-images-quickly-like-android/m-p/1487995#M187253
http://supportforums.blackberry.com/t5/Java-Development/Lazy-loading-issue-in-blackberry/m-p/1835127
You need to download images in a separate thread (not in UI Thread). Actually what happens when you render a list row , it looks for bitmap image.
So what you can do once you are creating your List view. Provide a default loading bitmap image, start a thread to download image ,
you should create method on thread where you are putting the data from Url to vector. this could be in your connection class where you have extend as thread.
like this>>>>
getimagemethod(image[i]);
after you declare your method get the image string url to the method. like this>>
private void getimagemethod(String image2)
{
this.imageforlist = image2;
// you should declare imageforlist string as global string..
newBitmap1 = Util_ImageLoader.getImageFromUrl(imageforlist);
//newBitmap1 is also global Bitmap..**
}
after this put your bitmap which is newBitmap1 to the Vector like this>>
imagevct.addElement(newBitmap1);
here imagevct is vector which is also global**
**inorder to create global vector use this....
private Vector imagevct = new Vector();
now you are ready to draw the bitmap on your list
for that do it like this...
public void drawListRow(ListField list, Graphics g, int index, int y, int w) {
Bitmap imagee = (Bitmap) imagevct.elementAt(index);
g.drawBitmap(HPADDING, 15 + y, 60, 60, imagee , 0, 0);
}
Here HPADDING is>>>>
private static final int HPADDING = Display.getWidth() <= 320 ? 6 : 8;
this is just tutorial sample step by step..
if any query then you can post here...