I created an Expert Advisor that will open long and short positions based on some bands, there are the 1.6 band and 3.6 band, it sells at the 3.6 upper band, puts the tp at 1.6 lower band and sl at half the tp opposite to the entry. It has no bug or warning, but it simply doesn't work when I try to use it. Any help would be greatly appreciated.
#property description "Price Border strategy expert advisor by Razvan"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 White
#property indicator_color2 Red
#property indicator_color3 Lime
//Inputs
extern double Lots =1;
extern double MaximumRisk =2;
extern double DecreaseFactor=3;
extern string TimeFrame = "All tf";
extern int HalfLength = 61;
extern int Price = 0;
extern double ATRMultiplier = 1.6;
extern double ATRMultiplier1 = 3.6;
extern int ATRPeriod = 480;
extern bool Interpolate = TRUE;
extern bool alertsOn = TRUE;
extern bool alertsOnCurrent = FALSE;
extern bool alertsOnHighLow = TRUE;
extern bool alertsMessage = FALSE;
extern bool alertsSound = TRUE;
extern bool alertsEmail = FALSE;
double var_1[];
double var_2[];
double var_3[];
double var_4[];
double var_20[];
double var_30[];
string string_1;
bool bool_1;
bool bool_2;
int var_5;
string string_2 = "nothing";
datetime Gt_176;
string string_3[] = {"M1", "M5", "M15", "M30", "H1", "H4", "D1", "W1", "MN"};
int var_6[] = {1, 5, 15, 30, 60, 240, 1440, 10080, 43200};
int res;
//init function
int init() {
string str_4[256];
for (int i = 0; i < 256; i++) str_4[i] = CharToStr(i);
int var_7 = StrToInteger(str_4[67] + str_4[111] + str_4[112] + str_4[121] + str_4[32] + str_4[82] + str_4[105] + str_4[103] + str_4[104] + str_4[116] + str_4[32] +
str_4[169] + str_4[32] + str_4[75] + str_4[97] + str_4[122] + str_4[97] + str_4[111] + str_4[111] + str_4[32] + str_4[50] + str_4[48] + str_4[49] + str_4[49] + str_4[32]);
IndicatorBuffers(4);
HalfLength = MathMax(HalfLength, 1);
SetIndexBuffer(0, var_1);
SetIndexDrawBegin(0, HalfLength);
SetIndexBuffer(1, var_2);
SetIndexDrawBegin(1, HalfLength);
SetIndexBuffer(2, var_3);
SetIndexDrawBegin(2, HalfLength);
SetIndexBuffer(3, var_4);
string_1 = WindowExpertName();
bool_2 = TimeFrame == "returnBars";
if (bool_2) return (0);
bool_1 = TimeFrame == "calculateValue";
if (bool_1) return (0);
var_5 = func_3(TimeFrame);
IndicatorShortName(func_0(var_5) + " TMA bands )" + HalfLength + ")");
return (0);
}
//deinit function
int deinit() {
return (0);
}
//start function
int start() {
int var_7;
double double_1;
double double_2;
double double_3;
double double_31;
int var_8;
int var_9;
int var_10 = IndicatorCounted();
if (var_10 < 0) return (-1);
if (var_10 > 0) var_10--;
int var_11 = MathMin(Bars - 1, Bars - var_10 + HalfLength);
if (bool_2) {
var_1[0] = var_11 + 1;
return (0);
}
if (bool_1 || var_5 == Period()) {
for (int i = var_11; i >= 0; i--) {
double_1 = (HalfLength + 1) * iMA(NULL, 0, 1, 0, MODE_SMA, Price, i);
double_2 = HalfLength + 1;
var_7 = 1;
for (int var_12 = HalfLength; var_7 <= HalfLength; var_12--) {
double_1 += var_12 * iMA(NULL, 0, 1, 0, MODE_SMA, Price, i + var_7);
double_2 += var_12;
if (var_7 <= i) {
double_1 += var_12 * iMA(NULL, 0, 1, 0, MODE_SMA, Price, i - var_7);
double_2 += var_12;
}
var_7++;
}
double_3 = iATR(NULL, 0, ATRPeriod, i + 10) * ATRMultiplier;
double_31 = iATR(NULL, 0, ATRPeriod, i + 10) * ATRMultiplier1;
var_1[i] = double_1 / double_2;
var_2[i] = var_1[i] + double_3;
var_20[i] = var_1[i] + double_31;
var_30[i] = var_1[i] - double_31;
var_3[i] = var_1[i] - double_3;
var_4[i] = 0;
if (alertsOnHighLow) {
if (High[i] > var_2[i]) var_4[i] = 1;
if (Low[i] < var_3[i]) var_4[i] = -1;
} else {
if (Close[i] > var_2[i]) var_4[i] = 1;
if (Close[i] < var_3[i]) var_4[i] = -1;
}
}
if (!(!bool_1)) return (0);
func_1();
return (0);
}
var_11 = MathMax(var_11, MathMin(Bars - 1, iCustom(NULL, var_5, string_1, "returnBars", 0, 0) *
var_5 / Period()));
for (i = var_11; i >= 0; i--) {
var_8 = iBarShift(NULL, var_5, Time[i]);
var_1[i] = iCustom(NULL, var_5, string_1, "calculateTma", HalfLength, Price, ATRMultiplier,
ATRPeriod, 0, var_8);
var_2[i] = iCustom(NULL, var_5, string_1, "calculateTma", HalfLength, Price, ATRMultiplier,
ATRPeriod, 1, var_8);
var_3[i] = iCustom(NULL, var_5, string_1, "calculateTma", HalfLength, Price, ATRMultiplier,
ATRPeriod, 2, var_8);
var_4[i] = iCustom(NULL, var_5, string_1, "calculateTma", HalfLength, Price, ATRMultiplier,
ATRPeriod, 3, var_8);
if (var_5 <= Period() || var_8 == iBarShift(NULL, var_5, Time[i - 1])) continue;
if (Interpolate) {
var_9 = iTime(NULL, var_5, var_8);
for (int var_14 = 1; i + var_14 < Bars && Time[i + var_14] >= var_9; var_14++) {
}
for (var_14 = 1; var_12 < var_14; var_12++) {
var_1[i + var_12] = var_1[i] + (var_1[i + var_14] - var_1[i]) * var_12 / var_14;
var_2[i + var_12] = var_2[i] + (var_2[i + var_14] - var_2[i]) * var_12 / var_14;
var_3[i + var_12] = var_3[i] + (var_3[i + var_14] - var_3[i]) * var_12 / var_14;
}
}
}
func_1();
return (0);
}
//function1
void func_1() {
int var_10;
if (alertsOn) {
if (alertsOnCurrent) var_10 = 0;
else var_10 = 1;
var_10 = iBarShift(NULL, 0, iTime(NULL, var_5, var_10));
if (var_4[var_10] != var_4[var_10 + 1]) {
if (var_4[var_10] == 1.0) func_4(var_10, "up");
if (var_4[var_10] == -1.0) func_4(var_10, "down");
}
}
}
//function4
void func_4(int var_12, string str_5) {
string str_6;
if (string_2 != str_5 || Gt_176 != Time[var_12]) {
string_2 = str_5;
Gt_176 = Time[var_12];
str_6 = StringConcatenate(Symbol(), " at ", TimeToStr(TimeLocal(), TIME_SECONDS), " " +
func_0(var_5) + " TMA bands price penetrated ", str_5, " band");
if (alertsMessage) Alert(str_6);
if (alertsEmail) SendMail(StringConcatenate(Symbol(), "TMA bands "), str_6);
if (alertsSound) PlaySound("alert2.wav");
}
}
//function3
int func_3(string str_7) {
str_7 = func_2(str_7);
for (int var_7 = ArraySize(var_6) - 1; var_7 >= 0; var_7--)
if (str_7 == string_3[var_7] || str_7 == "" + var_6[var_7]) return (MathMax(var_6[var_7],
Period()));
return (Period());
}
//function0
string func_0(int var_12) {
for (int i = ArraySize(var_6) - 1; i >= 0; i--)
if (var_12 == var_6[i]) return (string_3[i]);
return ("");
}
//function2
string func_2(string str_7) {
int var_13;
string str_8 = str_7;
for (int var_11 = StringLen(str_7) - 1; var_11 >= 0; var_11--) {
var_13 = StringGetChar(str_8, var_11);
if ((var_13 > '`'` && var_13 < '{') || (var_13 > 'ß' && var_13 < 256)) str_8 = StringSetChar(str_8,
var_11, var_13 - 32);
else
if (var_13 > -33 && var_13 < 0) str_8 = StringSetChar(str_8, var_11, var_13 + 224);
}
return (str_8);
}
//Calculate open positions
int CalculateCurrentOrders(string symbol)
{
int buys=0,sells=0;
for(int i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if(OrderSymbol()==Symbol())
{
if(OrderType()==OP_BUY) buys++;
if(OrderType()==OP_SELL) sells++;
}
}
//return orders volume
if(buys>0) return(buys);
else return(-sells);
}
//Calculate optimal lot size
double LotsOptimized()
{
double lot=Lots;
int orders=HistoryTotal(); // history orders total
int losses=0; // number of losses orders without a break
//select lot size
lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);
//calculate number of losses orders without a break
if(DecreaseFactor>0)
{
for(int i=orders-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)
{
Print("Error in history!");
break;
}
if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL)
continue;
//---
if(OrderProfit()>0) break;
if(OrderProfit()<0) losses++;
}
if(losses>1)
lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
}
//return lot size
if(lot<1) lot=1;
return(lot);
}
//Check for open order conditions
void CheckForOpen()
{ int var_10 = IndicatorCounted();
int var_11 = MathMin(Bars - 1, Bars - var_10 + HalfLength);
for (int i = var_11; i >= 0; i--)
{if(High[i] > var_20[i] || Close[i] > var_20[i])
{
res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,var_20[i]+(fabs(var_20[i]-
var_3[i])/2),var_2[i],"",0,Red); //Symbol(),OP_BUY,1,price,3,stoploss,takeprofit,"My
order",16384,0,clrGreen
return;
}
//buy conditions
if(Low[i] < var_30[i] || Close[i] < var_30[i])
{
res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,var_30[i]-(fabs(var_30[i]-
var_2[i])/2),var_3[i],"",0,Green);
return;
}}
}
//Check for close order conditions
void CheckForClose()
{
if(Volume[0]>1) return;
for(int i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if(OrderSymbol()!=Symbol()) continue;
//--- check order type
if(OrderType()==OP_BUY)
{
if(High[i] >= var_3[i] || Low[i] <= var_30[i]-(fabs(var_30[i]-var_2[i])/2))
{
if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,White))
Print("OrderClose error ",GetLastError());
}
break;
}
if(OrderType()==OP_SELL)
{
if(Low[i] <= var_2[i] || High[i] >= var_20[i]+(fabs(var_20[i]-var_3[i])/2))
{
if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,White))
Print("OrderClose error ",GetLastError());
}
break;
}
}
}
//OnTick function
void OnTick()
{
//check for history and trading
if(Bars<100 || IsTradeAllowed()==false)
return;
//calculate open orders by current symbol
if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
else CheckForClose();
}
'
In the code bellow , Why we need slices ? and what does it for ?
//https://github.com/danginsburg/opengles-book-samples/blob/604a02cc84f9cc4369f7efe93d2a1d7f2cab2ba7/iPhone/Common/esUtil.h#L110
int esGenSphere(int numSlices, float radius, float **vertices,
float **texCoords, uint16_t **indices, int *numVertices_out) {
int numParallels = numSlices / 2;
int numVertices = (numParallels + 1) * (numSlices + 1);
int numIndices = numParallels * numSlices * 6;
float angleStep = (2.0f * ES_PI) / ((float) numSlices);
if (vertices != NULL) {
*vertices = malloc(sizeof(float) * 3 * numVertices);
}
if (texCoords != NULL) {
*texCoords = malloc(sizeof(float) * 2 * numVertices);
}
if (indices != NULL) {
*indices = malloc(sizeof(uint16_t) * numIndices);
}
for (int i = 0; i < numParallels + 1; i++) {
for (int j = 0; j < numSlices + 1; j++) {
int vertex = (i * (numSlices + 1) + j) * 3;
if (vertices) {
(*vertices)[vertex + 0] = radius * sinf(angleStep * (float)i) * sinf(angleStep * (float)j);
(*vertices)[vertex + 1] = radius * cosf(angleStep * (float)i);
(*vertices)[vertex + 2] = radius * sinf(angleStep * (float)i) * cosf(angleStep * (float)j);
}
if (texCoords) {
int texIndex = (i * (numSlices + 1) + j) * 2;
(*texCoords)[texIndex + 0] = (float)j / (float)numSlices;
(*texCoords)[texIndex + 1] = 1.0f - ((float)i / (float)numParallels);
}
}
}
// Generate the indices
if (indices != NULL) {
uint16_t *indexBuf = (*indices);
for (int i = 0; i < numParallels ; i++) {
for (int j = 0; j < numSlices; j++) {
*indexBuf++ = i * (numSlices + 1) + j;
*indexBuf++ = (i + 1) * (numSlices + 1) + j;
*indexBuf++ = (i + 1) * (numSlices + 1) + (j + 1);
*indexBuf++ = i * (numSlices + 1) + j;
*indexBuf++ = (i + 1) * (numSlices + 1) + (j + 1);
*indexBuf++ = i * (numSlices + 1) + (j + 1);
}
}
}
if (numVertices_out) {
*numVertices_out = numVertices;
}
return numIndices;
}
That code generates a sphere mesh that looks like this:
Source: https://commons.wikimedia.org/wiki/File:Sphere_wireframe_10deg_6r.svg CC BY 3.0
As you can see in the picture, there are horizontal parallel lines, and vertical lines which all meet at the poles. The horizontal lines are typically called parallels whereas the vertical ones are called meridians. The author of that code apparently didn't know this term, so they called it "slices" instead.
I tried to create Fill and Eraser Tools by GDI but this way is too slow for windows phone devices and work with large photos with this method is too hard for this divices.
I search for Alternative soulation for Image Processing and find Win2D and Sharpdx but not sure These Api can help me for create these tools.
this is Fill tool in winrtxamltoolkit
public static void FloodFill(this WriteableBitmap target, int x, int y, int outlineColor, int fillColor, byte maxdiff)
{
var width = target.PixelWidth;
var height = target.PixelHeight;
var queue = new List<Pnt>();
using (var context = target.GetBitmapContext(ReadWriteMode.ReadWrite))
{
queue.Add(new Pnt { X = x, Y = y });
while (queue.Count > 0)
{
var p = queue[queue.Count - 1];
queue.RemoveAt(queue.Count - 1);
if (p.X == -1) continue;
if (p.X == width) continue;
if (p.Y == -1) continue;
if (p.Y == height) continue;
if (context.Pixels[width * p.Y + p.X] == outlineColor) continue;
if (context.Pixels[width * p.Y + p.X] == fillColor) continue;
if (context.Pixels[width * p.Y + p.X].MaxDiff(outlineColor) > maxdiff)
{
context.Pixels[width * p.Y + p.X] = fillColor;
}
else
{
continue;
}
context.Pixels[width * p.Y + p.X] = fillColor;
queue.Add(new Pnt { X = p.X, Y = p.Y - 1 });
queue.Add(new Pnt { X = p.X + 1, Y = p.Y });
queue.Add(new Pnt { X = p.X, Y = p.Y + 1 });
queue.Add(new Pnt { X = p.X - 1, Y = p.Y });
}
target.Invalidate();
}
}
and this is Ereaser tool in WriteableBitmapEx
public static void FillEllipseCenteredTrsnceparent(this WriteableBitmap bmp, int xc, int yc, int xr, int yr, Color color)
{
using (BitmapContext context = bmp.GetBitmapContext())
{
Func<Color, int> toInt32 = c =>
{
var i = ((((c.A << 0x18) | (((c.R * c.A + 1) >> 8) << 0x10)) | (((c.G * c.A + 1) >> 8) << 8)) | ((c.B * c.A + 1) >> 8));
return i;
};
int[] pixels = context.Pixels;
int width = context.Width;
int height = context.Height;
if ((xr >= 1) && (yr >= 1))
{
int num3;
int num4;
int num5;
int num6;
int num7;
int num8;
int num9 = xr;
int num10 = 0;
int num11 = (xr * xr) << 1;
int num12 = (yr * yr) << 1;
int num13 = (yr * yr) * (1 - (xr << 1));
int num14 = xr * xr;
int num15 = 0;
int num16 = num12 * xr;
int num17 = 0;
//int sa = (color >> 0x18) & 0xff;
//int sr = (color >> 0x10) & 0xff;
//int sg = (color >> 8) & 0xff;
//int sb = color & 0xff;
//bool flag = !doAlphaBlend || (sa == 0xff);
while (num16 >= num17)
{
num5 = yc + num10;
num6 = yc - num10;
if (num5 < 0)
{
num5 = 0;
}
if (num5 >= height)
{
num5 = height - 1;
}
if (num6 < 0)
{
num6 = 0;
}
if (num6 >= height)
{
num6 = height - 1;
}
num3 = num5 * width;
num4 = num6 * width;
num8 = xc + num9;
num7 = xc - num9;
if (num8 < 0)
{
num8 = 0;
}
if (num8 >= width)
{
num8 = width - 1;
}
if (num7 < 0)
{
num7 = 0;
}
if (num7 >= width)
{
num7 = width - 1;
}
for (int i = num7; i <= num8; i++)
{
pixels[i + num3] = toInt32(color);
pixels[i + num4] = toInt32(color);
}
num10++;
num17 += num11;
num15 += num14;
num14 += num11;
if ((num13 + (num15 << 1)) > 0)
{
num9--;
num16 -= num12;
num15 += num13;
num13 += num12;
}
}
num9 = 0;
num10 = yr;
num5 = yc + num10;
num6 = yc - num10;
if (num5 < 0)
{
num5 = 0;
}
if (num5 >= height)
{
num5 = height - 1;
}
if (num6 < 0)
{
num6 = 0;
}
if (num6 >= height)
{
num6 = height - 1;
}
num3 = num5 * width;
num4 = num6 * width;
num13 = yr * yr;
num14 = (xr * xr) * (1 - (yr << 1));
num15 = 0;
num16 = 0;
num17 = num11 * yr;
while (num16 <= num17)
{
num8 = xc + num9;
num7 = xc - num9;
if (num8 < 0)
{
num8 = 0;
}
if (num8 >= width)
{
num8 = width - 1;
}
if (num7 < 0)
{
num7 = 0;
}
if (num7 >= width)
{
num7 = width - 1;
}
for (int j = num7; j <= num8; j++)
{
pixels[j + num3] = toInt32(color);
pixels[j + num4] = toInt32(color);
}
num9++;
num16 += num12;
num15 += num13;
num13 += num12;
if ((num14 + (num15 << 1)) > 0)
{
num10--;
num5 = yc + num10;
num6 = yc - num10;
if (num5 < 0)
{
num5 = 0;
}
if (num5 >= height)
{
num5 = height - 1;
}
if (num6 < 0)
{
num6 = 0;
}
if (num6 >= height)
{
num6 = height - 1;
}
num3 = num5 * width;
num4 = num6 * width;
num17 -= num11;
num15 += num14;
num14 += num11;
}
}
}
}
}
Is there a way to conver this code to win2d or Sharpdx?
Hello I am trying to convert an ARGB 8888 image into yuv 420 sp in android and I am getting a totally greenish and compressed image.Please help me in code if I am doing it the correct way.
The code seems something as below.
Image(Context context) {
// This Constructor is used to initialize height and width of screen
screenHeight = 800;//m1.heightPixels;
screenWidth = 480;//m1.widthPixels;
bufferSize = 4 * screenHeight * screenWidth;
buffer = new byte[bufferSize];
newarrs =new byte[bufferSize];
log("constructor width:- " + screenWidth + " height:- " + screenHeight);
}
public void capture() {
// Take the Data from frame buffer and store in buffer
log("capture Screen");
BufferedInputStream bis = null;
try {
// log("in try");
bis = new BufferedInputStream(new FileInputStream("/data/fb0.raw"));
readSize = bis.read(buffer, 0, bufferSize);
bis.close();
}
catch (Exception e) {
// log("in catch");
e.printStackTrace();
}
encodeYUV420(buffer);
byte[] arr = resize1(buffer);
FileOutputStream fos;
try {
File f = Files.getImageFile();
fos = new FileOutputStream(f);
fos.write(arr);
fos.close();
} catch (Exception e) {
}
private byte[] resize1(byte[] buffer) {
final int RATIO = 4;
byte[][][] newBuff = new byte[screenWidth][screenHeight][4];
int pos1 = 0;
for (int i = 0; i < screenWidth; i++) {
for (int j = 0; j < screenHeight; j++) {
newBuff[i][j][0] = buffer[pos1++];
newBuff[i][j][1] = buffer[pos1++];
newBuff[i][j][2] = buffer[pos1++];
newBuff[i][j][3] = buffer[pos1++];
}
}
byte[] buffer1 = new byte[buffer.length*3 / (RATIO * RATIO)];
int pos2 = 0;
int i = 0, j = 0;
for (i = 0; i < screenWidth; i++) {
for (j = 0; j < screenHeight; j++) {
try {
if (i % RATIO == 0 && j % RATIO == 0) {
buffer1[pos2++] = newBuff[i][j][0];
buffer1[pos2++] = newBuff[i][j][1];
buffer1[pos2++] = newBuff[i][j][2];
buffer1[pos2++] = newBuff[i][j][3];
}
} catch (Exception e) {
log(" i " + i + " j " + j);
}
}
}
log(" valuesof i " + i + " j " + j);
if (pos2 == buffer.length / (RATIO * RATIO))
log("S size:- " + pos2);
else
log("F size:- " + pos2);
return buffer1;
}
private byte[] encodeYUV420(byte[] argb) {
byte[] yuv420sp = new byte[(screenHeight * screenWidth * 3) / 2];
final int frameSize = screenWidth * screenHeight;
int yIndex = 0;
int uIndex = frameSize;
int vIndex = frameSize + (frameSize / 4);
int R, G, B;
int Y, U, V;
int index = 0;
for (int j = 0; j < screenHeight; j++) {
for (int i = 0; i < screenWidth; i++) {
int pp = (j * screenWidth + i) * 4;
//a = (argb[index] & 0xff000000) >> 24; // a is not used obviously
R = (argb[index] & 0xff0000) >> 16;
G = (argb[index] & 0xff00) >> 8;
B = (argb[index] & 0xff) >> 0;
Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;
yuv420sp[yIndex++] = (byte) ((Y < 0) ? 0 : ((Y > 255) ? 255 : Y));
if (j % 2 == 0 && i % 2 == 0) {
yuv420sp[uIndex++] = (byte) ((U<0) ? 0 : ((U > 255) ? 255 : U));
yuv420sp[vIndex++] = (byte) ((V<0) ? 0 : ((V > 255) ? 255 : V));
}
}
return yuv420sp;
}
Update:
Screenshot illustrating the problem:
I think I have made some changes and it looks some what as the original image but it is not clear or legible.Can I get some ideas on how to make it almost as the original image
Image(Context context) {
// This Constructor is used to initialize height and width of screen
screenHeight = 800;//m1.heightPixels;
screenWidth = 480;//m1.widthPixels;
bufferSize = 4 * screenHeight * screenWidth;
buffer = new byte[bufferSize];
newarrs =new byte[bufferSize];
log("constructor width:- " + screenWidth + " height:- " + screenHeight);
}
public void capture() {
// Take the Data from frame buffer and store in buffer
log("capture Screen");
BufferedInputStream bis = null;
try {
// log("in try");
bis = new BufferedInputStream(new FileInputStream("/data/fb0.raw"));
readSize = bis.read(buffer, 0, bufferSize);
bis.close();
}
catch (Exception e) {
// log("in catch");
e.printStackTrace();
}
encodeYUV420(buffer);
byte[] arr = resize1(buffer);
FileOutputStream fos;
try {
File f = Files.getImageFile();
fos = new FileOutputStream(f);
fos.write(arr);
fos.close();
} catch (Exception e) {
}
private byte[] resize1(byte[] buffer) {
final int RATIO = 4;
byte[][][] newBuff = new byte[screenWidth][screenHeight][4];
int pos1 = 0;
for (int i = 0; i < screenWidth; i++) {
for (int j = 0; j < screenHeight; j++) {
newBuff[i][j][0] = buffer[pos1++];
newBuff[i][j][1] = buffer[pos1++];
newBuff[i][j][2] = buffer[pos1++];
newBuff[i][j][3] = buffer[pos1++];
}
}
byte[] buffer1 = new byte[buffer.length*3 / (RATIO * RATIO)];
int pos2 = 0;
int i = 0, j = 0;
for (i = 0; i < screenWidth; i++) {
for (j = 0; j < screenHeight; j++) {
try {
if (i % RATIO == 0 && j % RATIO == 0) {
buffer1[pos2++] = newBuff[i][j][0];
buffer1[pos2++] = newBuff[i][j][1];
buffer1[pos2++] = newBuff[i][j][2];
buffer1[pos2++] = newBuff[i][j][3];
}
} catch (Exception e) {
log(" i " + i + " j " + j);
}
}
}
log(" valuesof i " + i + " j " + j);
if (pos2 == buffer.length / (RATIO * RATIO))
log("S size:- " + pos2);
else
log("F size:- " + pos2);
return buffer1;
}
private byte[] encodeYUV420(byte[] argb) {
byte[] yuv420sp = new byte[(screenHeight * screenWidth * 3) / 2];
final int frameSize = screenWidth * screenHeight;
int yIndex = 0;
int uvIndex=frameSize;
int a, R, G, B, Y, U, V;
int index = 0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
int pp = (j * width + i) * 4;
R = argb[pp+ 0];
G = argb[pp + 1];
B = argb[pp + 2];
a = argb[pp + 3];
Y = ( ( 66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
U = ( ( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
V = ( ( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128;
yuv420sp[yIndex++] = (byte) ((Y < 0) ? 0 : ((Y > 255) ? 255 : Y));
if (j % 2 == 0 && i % 2 == 0) {
yuv420sp[uvIndex++] = (byte)((U<0) ? 0 : ((U > 255) ? 255 : U));
yuv420sp[uvIndex++] = (byte)((V<0) ? 0 : ((V > 255) ? 255 : V));
}
}
return yuv420sp;
}
You're not storing the YUV data correctly. According to this document, YUV420SP data is stored in two planes, one containing the Y data, and another containing the interleaved U and V data:
| Y_0 | Y_1 | Y_2 | Y_3 | Y_4 | ... | Y_w-2 | Y_w-1 | /* h rows */
| Y_w | Y_w+1 | Y_w+2 | ...
:
:
| U_0 | V_0 | U_2 | V_2 | U_4 | ... | U_w-2 | V_w-2 | /* h/2 rows */
| U_2w | V_2w | U_2w+2| ...
:
:
Your code seems to be storing the U and V data in separate planes:
int uIndex = frameSize;
int vIndex = frameSize + (frameSize / 4);
There is a perspective image issue when I read a picture that is taken from the camera. When the direction is north, the picture looks like needed to be rotated 270 degrees. When the direction is east, picture should be rotated 180 degrees. But it's good when the direction is west. I tried getMetaData().getKeyValue("orientation") in EncodedImage for producing a good rotating formula, but it returned empty string. Please help me how to solve this problem.
Found solution here:
https://gist.github.com/3788313
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.EncodedImage;
public class ExifRotate {
/**
* Flip the image horizontally.
*/
public static final int FLIP_H = 1;
/**
* Flip the image vertically.
*/
public static final int FLIP_V = 2;
/**
* Flip the image horizontally and vertically.
*/
public static final int FLIP_HV = 3;
/**
* Rotate the image 90 degrees clockwise.
*/
public static final int FLIP_90CW = 4;
/**
* Rotate the image 90 degrees counter-clockwise.
*/
public static final int FLIP_90CCW = 5;
/**
* Rotate the image 180 degrees.
*/
public static final int FLIP_180 = 6;
private final static int read2bytes(InputStream in) throws IOException {
return in.read() << 8 | in.read();
}
private final static int readByte(InputStream in) throws IOException {
return in.read();
}
public static Bitmap readImageFromFile(String filename, int width, int height) throws IOException {
EncodedImage img = null;
byte[] data = null;
FileConnection file = null;
try {
file = (FileConnection) Connector.open(filename, Connector.READ);
int fileSize = (int) file.fileSize();
if (fileSize == 0) {
throw new IOException("File is empty");
}
data = new byte[fileSize];
InputStream input = file.openInputStream();
input.read(data);
input.close();
img = EncodedImage.createEncodedImage(data, 0, data.length);
int orientation = -1;
if ( filename.toLowerCase().endsWith(".jpg") || filename.toLowerCase().endsWith(".jpeg")) {
ByteArrayInputStream is = new ByteArrayInputStream( data );
orientation = getRotation(is);
}
if ( orientation == 2 ) {
return rotateBitmap(img.getBitmap(), ImageUtil.FLIP_H);
} else if ( orientation == 3 ) {
return rotateBitmap(img.getBitmap(), ImageUtil.FLIP_180);
} else if ( orientation == 4 ) {
return rotateBitmap(img.getBitmap(), ImageUtil.FLIP_V);
} else if ( orientation == 5 ) {
Bitmap tmp = rotateBitmap(img.getBitmap(), ImageUtil.FLIP_H);
tmp = rotateBitmap(tmp, ImageUtil.FLIP_90CCW);
return tmp;
} else if ( orientation == 6 ) {
return rotateBitmap(img.getBitmap(), ImageUtil.FLIP_90CW);
} else if ( orientation == 7 ) {
Bitmap tmp = rotateBitmap(img.getBitmap(), ImageUtil.FLIP_H);
tmp = rotateBitmap(tmp, ImageUtil.FLIP_90CW);
return tmp;
} else if ( orientation == 8 ) {
return rotateBitmap(img.getBitmap(), ImageUtil.FLIP_90CCW);
} else {
return img.getBitmap();
}
} finally {
if (file != null) {
try { file.close(); }
catch(Exception ex){}
}
}
}
public static int getRotation(InputStream in) throws IOException {
int [] exif_data = new int[100];
int n_flag = 0, set_flag = 0;
int is_motorola = 0;
/* Read File head, check for JPEG SOI + Exif APP1 */
for (int i = 0; i < 4; i++)
exif_data[i] = readByte(in);
if (exif_data[0] != 0xFF || exif_data[1] != 0xD8 || exif_data[2] != 0xFF || exif_data[3] != 0xE1)
return -2;
/* Get the marker parameter length count */
int length = read2bytes(in);
// exif_data = new int[length];
/* Length includes itself, so must be at least 2 */
/* Following Exif data length must be at least 6 */
if (length < 8)
return -1;
length -= 8;
/* Read Exif head, check for "Exif" */
for (int i = 0; i < 6; i++)
exif_data[i] = in.read();
if (exif_data[0] != 0x45 || exif_data[1] != 0x78 || exif_data[2] != 0x69 || exif_data[3] != 0x66 || exif_data[4] != 0 || exif_data[5] != 0)
return -1;
/* Read Exif body */
length = length > exif_data.length ? exif_data.length : length;
for (int i = 0; i < length; i++)
exif_data[i] = in.read();
if (length < 12)
return -1; /* Length of an IFD entry */
/* Discover byte order */
if (exif_data[0] == 0x49 && exif_data[1] == 0x49)
is_motorola = 0;
else if (exif_data[0] == 0x4D && exif_data[1] == 0x4D)
is_motorola = 1;
else
return -1;
/* Check Tag Mark */
if (is_motorola == 1) {
if (exif_data[2] != 0)
return -1;
if (exif_data[3] != 0x2A)
return -1;
} else {
if (exif_data[3] != 0)
return -1;
if (exif_data[2] != 0x2A)
return -1;
}
/* Get first IFD offset (offset to IFD0) */
int offset;
if (is_motorola == 1) {
if (exif_data[4] != 0)
return -1;
if (exif_data[5] != 0)
return -1;
offset = exif_data[6];
offset <<= 8;
offset += exif_data[7];
} else {
if (exif_data[7] != 0)
return -1;
if (exif_data[6] != 0)
return -1;
offset = exif_data[5];
offset <<= 8;
offset += exif_data[4];
}
if (offset > length - 2)
return -1; /* check end of data segment */
/* Get the number of directory entries contained in this IFD */
int number_of_tags;
if (is_motorola == 1) {
number_of_tags = exif_data[offset];
number_of_tags <<= 8;
number_of_tags += exif_data[offset + 1];
} else {
number_of_tags = exif_data[offset + 1];
number_of_tags <<= 8;
number_of_tags += exif_data[offset];
}
if (number_of_tags == 0)
return -1;
offset += 2;
/* Search for Orientation Tag in IFD0 */
for (;;) {
if (offset > length - 12)
return -1; /* check end of data segment */
/* Get Tag number */
int tagnum;
if (is_motorola == 1) {
tagnum = exif_data[offset];
tagnum <<= 8;
tagnum += exif_data[offset + 1];
} else {
tagnum = exif_data[offset + 1];
tagnum <<= 8;
tagnum += exif_data[offset];
}
if (tagnum == 0x0112)
break; /* found Orientation Tag */
if (--number_of_tags == 0)
return -1;
offset += 12;
}
/*
* if (set_flag==1) { Set the Orientation value if (is_motorola==1) {
* exif_data[offset+2] = 0; Format = unsigned short (2 octets)
* exif_data[offset+3] = 3; exif_data[offset+4] = 0; Number Of
* Components = 1 exif_data[offset+5] = 0; exif_data[offset+6] = 0;
* exif_data[offset+7] = 1; exif_data[offset+8] = 0; exif_data[offset+9]
* = set_flag; exif_data[offset+10] = 0; exif_data[offset+11] = 0; }
* else { exif_data[offset+2] = 3; Format = unsigned short (2 octets)
* exif_data[offset+3] = 0; exif_data[offset+4] = 1; Number Of
* Components = 1 exif_data[offset+5] = 0; exif_data[offset+6] = 0;
* exif_data[offset+7] = 0; exif_data[offset+8] = set_flag;
* exif_data[offset+9] = 0; exif_data[offset+10] = 0;
* exif_data[offset+11] = 0; } }
*/
// else {
/* Get the Orientation value */
if (is_motorola == 1) {
if (exif_data[offset + 8] != 0)
return -1;
set_flag = exif_data[offset + 9];
} else {
if (exif_data[offset + 9] != 0)
return -1;
set_flag = exif_data[offset + 8];
}
if (set_flag > 8)
return -1;
// }
/* Write out Orientation value */
if (n_flag == 1)
System.out.println("set_flag " + set_flag);
else
System.out.println("set_flag " + set_flag);
return set_flag;
}
public static Bitmap rotateBitmap(Bitmap src, int operation) {
int width = src.getWidth();
int height = src.getHeight();
int[] inPixels = new int[width*height];
src.getARGB(inPixels, 0, width, 0, 0, width, height);
int x = 0, y = 0;
int w = width;
int h = height;
int newX = 0;
int newY = 0;
int newW = w;
int newH = h;
switch (operation) {
case FLIP_H:
newX = width - (x + w);
break;
case FLIP_V:
newY = height - (y + h);
break;
case FLIP_HV:
newW = h;
newH = w;
newX = y;
newY = x;
break;
case FLIP_90CW:
newW = h;
newH = w;
newX = height - (y + h);
newY = x;
break;
case FLIP_90CCW:
newW = h;
newH = w;
newX = y;
newY = width - (x + w);
break;
case FLIP_180:
newX = width - (x + w);
newY = height - (y + h);
break;
}
int[] newPixels = new int[newW * newH];
int index, newRow, newCol, newIndex;
if ( operation == FLIP_H ) {
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
index = row * width + col;
newRow = row;
newCol = w - col - 1;
newIndex = newRow * newW + newCol;
newPixels[newIndex] = inPixels[index];
}
}
} else if ( operation == FLIP_V ) {
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
index = row * width + col;
newRow = h - row - 1;
newCol = col;
newIndex = newRow * newW + newCol;
newPixels[newIndex] = inPixels[index];
}
}
} else if ( operation == FLIP_HV ) {
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
index = row * width + col;
newRow = col;
newCol = row;
newIndex = newRow * newW + newCol;
newPixels[newIndex] = inPixels[index];
}
}
} else if ( operation == FLIP_90CW ) {
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
index = row * width + col;
newRow = col;
newCol = h - row - 1;
newIndex = newRow * newW + newCol;
newPixels[newIndex] = inPixels[index];
}
}
} else if ( operation == FLIP_90CCW ) {
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
index = row * width + col;
newRow = w - col - 1;
newCol = row;
newIndex = newRow * newW + newCol;
newPixels[newIndex] = inPixels[index];
}
}
} else if ( operation == FLIP_180 ) {
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
index = row * width + col;
newRow = h - row - 1;
newCol = w - col - 1;
newIndex = newRow * newW + newCol;
newPixels[newIndex] = inPixels[index];
}
}
}
Bitmap dst = new Bitmap( newW, newH );
dst.setARGB(newPixels, 0, newW, 0, 0, newW, newH);
return dst;
}
}