martes, 13 de agosto de 2013

RaspberryPi Python Sound Player

La idea es construir un script en python que permita la reproducción de un set de canciones para la presentación cambios de escena de un pequeño proyecto de teatro infantil controlado por arduino.


Vamos a conectar la RaspberryPi con el Arduino Leonardo ya este modelo permite usar el usb como entradas de teclado bueno, eso estamos en desarrollo.

Mencionare brevemente lo que se va hacer pero ya tenemos el primer punto que es el script que permite reproducir el audio en un ciclo inifinito y cambiar de cancion por el teclado.

  1. Bajar e instalar el moebius, ya que esta versión elimina el entorno X server y el lxde escritorios y entorno gráfico de la versión Raspbian. Ademas que me va a permitir un booteo rapido de la Pi. (listo)
  2. Configurar el Auto Arranque del usuario en la Pi, pues en un sistema embebido no tienes que poner login para iniciar tu programa. (pendiente).
  3. Instalar el python en la Pi (OK)

  • apt-get install python

  1. Instalar el mpg123 via APT en la Pi, este ejecutable permite la reproducción de audio por consola. (OK)


  1. Cargar el programa en python en el auto login de la Pi (Pendiente)
  2. Crear el programa en python que permite por entrada de teclado y este debera ser activado por el Arduino Leonardo (listo)

el programa en python: player.py

Enlace del script

https://dl.dropboxusercontent.com/u/14805656/python/player.py

Bueno esta probado en cygwin pero he aquí algunas pantallas del funcionamiento:









martes, 4 de diciembre de 2012

Instalacion de Android SDK Offline

Describo los pasos para la isntalacion 100% funcional de l version de android 2.3.3 en windows 7 fuera de linea.

  • Tener el JDK de java 7 bajar en la siguiente direccion:
http://www.oracle.com/technetwork/java/javase/downloads/java-se-jdk-7-download-432154.html

Nota: Bajar la version del jdk que termine en i586 intentar con este archivo jdk-7-windows-i586.exe

  • Bajar el instalador de la pagina de android para windows esto lo hize en la siguiente direccion:
http://developer.android.com/sdk/index.html

Bueno aqui es un poco confuso por que la pagina es diferente; lo que necesitamos esta en la parte inferior DOWNLOAD FOR OTHER PLATFORMS
El link es http://dl.google.com/android/installer_r21-windows.exe

  • Bueno este instalador recomiendo usar la ruta de instalación en windows en C:\; el resto es el clasico asistente(siguiente, siguiente, finalizar);


  • Abrimos el SDK Manager y bueno este tratara de conectarse a internet; cerramos la ventana de log y comprobamos lo que tenemos instalado. Esto se debe hacer para verificar el numero de revision para bajar las herramientas de desarrollo en la ventana tiene el nombre de Plataforms-tools describo en la siguiente imagen lo que he escrito. Desactivar todos los check ya que el instalador siempre busca la ultima version de android para que la instales pero en este caso nosotros decidimos que version queremos.


La clave esta en el numero magico que indica la revision que debemos bajar de acuerdo al instalador que bajamos inicialmente.
La url es la siguiente:

http://dl-ssl.google.com/android/repository/platform-tools_r16-windows.zip

Nota la r16 es igual a la que muestra la pantalla si en la pantalla te sale otro numero solo editas el link y bajas la version que necesitas

Lo ultimo que necesitamos descargar es el imagen de Android 2.3.3 a nuestro equipo miramos que numero de revision de la pantalla y hacemos lo mismo que el paso anterior.

La Url:

http://dl-ssl.google.com/android/repository/android-2.3.3_r02-linux.zip

Nuevamente el numero mágico r02 indica que esta es la correcta a bajar

Bueno armado con los dos zip creamos la carpeta temp. La pregunta donde? en la siguiente ruta:

C:\Android\android-sdk

Copiamos y pegamos los zip dentro de esa carpeta nos debe quedar asi:

Ahora desconectamos el internet de nuestra pc para comprobar que todo va ok y damos check a las opciones que ya había mencionado debería quedar de la siguiente forma:
Damos click en Install 2 packages y esto lee los zip de la carpeta temp y listo ya tienes tu android listo para empezar a desarrollar. Para comprobar finalmente que todo estuvo ok.

URL para bajar los ejemplos de esta sdk

http://dl-ssl.google.com/android/repository/samples-2.3.3_r01-linux.zip

Crea un emulador usando el ADVMaganer en target debe salir la versión de android que bajamos.

Actualizacion:
Google ya tiene un paquete (ADT Bundle for Windows) todo en uno con la ultima version de android y pesa 399 MB no estoy seguro; bueno donde esta ese mega zip:

http://developer.android.com/sdk/index.html


sábado, 15 de enero de 2011

Leer Datos de un Teclado USB HID RawInput Vb6

Para aquellas personas que quieran usar un dispositivo USB HID como un teclado o lector de código de barras que solo acepte entradas de este dispositivo subo este codigo de tal forma que les ayude hace uso de la API de windows:

http://msdn.microsoft.com/en-us/library/ms645536%28v=vs.85%29.aspx

Primero empezamos con el código del modulo:

' Standardmodul Module1
Option Explicit

Public counter As Integer
'Set you Keyboard HID whit VendorID and ProductID
Public Const Device_Name = "VID_04B4&PID_0168"

Private Declare Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" ( _
ByVal hwnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long

Private Declare Function CallWindowProc Lib "user32" _
Alias "CallWindowProcA" ( _
ByVal lpPrevWndFunc As Long, _
ByVal hwnd As Long, _
ByVal Msg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long

Declare Function SetClipboardViewer Lib "user32" ( _
ByVal hwnd As Long) As Long

Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
ByRef Destination As Any, _
ByRef Source As Any, _
ByVal ByteLen As Long)

'UINT GetRawInputDeviceList(
'    PRAWINPUTDEVICELIST pRawInputDeviceList,
'    PUINT puiNumDevices,
'    UINT cbSize
');
Private Declare Function GetRawInputDeviceList Lib "user32.dll" ( _
ByRef pRawInputDeviceList As Any, _
ByRef puiNumDevices As Any, _
ByVal cbSize As Long) As Long

'BOOL RegisterRawInputDevices(
'    PCRAWINPUTDEVICE pRawInputDevices,
'    UINT uiNumDevices,
'    UINT cbSize
');
Private Declare Function RegisterRawInputDevices Lib "user32.dll" ( _
ByRef pRawInputDevices As RAWINPUTDEVICE, _
ByVal uiNumDevices As Long, _
ByVal cbSize As Long) As Long

'UINT GetRawInputData(
'    HRAWINPUT hRawInput,
'    UINT uiCommand,
'    LPVOID pData,
'    PUINT pcbSize,
'    UINT cbSizeHeader
');
Private Declare Function GetRawInputData Lib "user32.dll" ( _
ByVal hRawInput As Long, _
ByVal uiCommand As Long, _
ByRef pData As Any, _
ByRef pcbSize As Long, _
ByVal cbSizeHeader As Long) As Long

Public Enum DeviceInfoTypes
RIDI_PREPARSEDDATA = &H20000005
RIDI_DEVICENAME = &H20000007
RIDI_DEVICEINFO = &H2000000B
End Enum

'UINT GetRawInputDeviceInfo(
'      HANDLE hDevice,
'      UINT uiCommand,
'      LPVOID pData,
'      PUINT pcbSize
');
Private Declare Function GetRawInputDeviceInfo Lib "user32.dll" 
Alias "GetRawInputDeviceInfoA" ( _
ByVal hDevice As Long, _
ByVal uiCommand As DeviceInfoTypes, _
ByRef pData As Any, _
ByRef pcbSize As Long) As Long


Private Const RIM_TYPEMOUSE = &H0&
Private Const RIM_TYPEKEYBOARD = &H1&
Private Const RID_INPUT = &H10000003
Private Const WM_INPUT = &HFF&
Private Const GWL_WNDPROC = -4&
Private Const RIDEV_INPUTSINK = &H100

'typedef struct tagRAWINPUTDEVICE {
'    USHORT usUsagePage;
'    USHORT usUsage;
'    DWORD dwFlags;
'    HWND hwndTarget;
'} RAWINPUTDEVICE, *PRAWINPUTDEVICE, *LPRAWINPUTDEVICE;
Private Type RAWINPUTDEVICE
usUsagePage As Integer
usUsage As Integer
dwFlags As Long
hwnd As Long
End Type

'typedef struct tagRAWINPUTDEVICELIST {
'    HANDLE hDevice;
'    DWORD dwType;
'} RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST;
Private Type RAWINPUTDEVICELIST
hDevice As Long
dwType As Long
End Type

'typedef struct tagRAWINPUTHEADER {
'    DWORD dwType;
'    DWORD dwSize;
'    HANDLE hDevice;
'    WPARAM wParam;
'} RAWINPUTHEADER, *PRAWINPUTHEADER;
Private Type RAWINPUTHEADER
dwType As Long
dwSize As Long
hDevice As Long
wParam As Long
End Type

'typedef struct tagRAWMOUSE {
'  USHORT    usFlags;
'  union {
'         ULONG    ulButtons;
'             struct {
'                       USHORT usButtonFlags;
'                       USHORT usButtonData;
'                       };
'  };
'  ULONG ulRawButtons;
'  LONG  lLastX;
'  LONG  lLastY;
'  ULONG ulExtraInformation;
'} RAWMOUSE, *PRAWMOUSE, *LPRAWMOUSE;
Private Type RAWMOUSE
usFlags As Integer
ulButtons As Long
ulRawButtons As Long
lLastX As Long
lLastY As Long
ulExtraInformation As Long
End Type

'typedef struct tagRAWKEYBOARD {
'  USHORT MakeCode;
'  USHORT Flags;
'  USHORT Reserved;
'  USHORT VKey;
'  UINT   Message;
'  ULONG  ExtraInformation;
'} RAWKEYBOARD, *PRAWKEYBOARD, *LPRAWKEYBOARD;
Private Type RAWKEYBOARD
MakeCode As Integer
Flags As Integer
Reserved As Integer
VKey As Integer
Message As Long
ExtraInformation As Long
End Type

'typedef struct tagRAWINPUT {
'    RAWINPUTHEADER    header;
'    union {
'             RAWMOUSE    mouse;
'             RAWKEYBOARD keyboard;
'             RAWHID      hid;
'            } data;
'} RAWINPUT, *PRAWINPUT; *LPRAWINPUT;
Private Type RAWINPUT
header As RAWINPUTHEADER
'data As RAWMOUSE
data As RAWKEYBOARD
End Type

Dim PrevWndProc As Long, mWnd As Long, txtBox As TextBox

Public Sub Init(ByVal hwnd As Long, ByVal text As TextBox)
mWnd = hwnd
Set txtBox = text
PrevWndProc = SetWindowLong(mWnd, GWL_WNDPROC, AddressOf MainWndProc)
InitRawInput mWnd
End Sub

Public Sub Terminate()
Call SetWindowLong(mWnd, GWL_WNDPROC, PrevWndProc)
End Sub

Public Sub InitRawInput(hwnd As Long)
Dim RID(49) As RAWINPUTDEVICE

Dim nDevices As Long
Dim pRawInputDeviceList() As RAWINPUTDEVICELIST
ReDim pRawInputDeviceList(0)

If GetRawInputDeviceList(ByVal 0&, nDevices, Len(pRawInputDeviceList(0))) <> 0 Then
Exit Sub
End If

ReDim pRawInputDeviceList(nDevices - 1)
Call GetRawInputDeviceList(pRawInputDeviceList(0), nDevices, Len(pRawInputDeviceList(1)))
Debug.Print "Number of raw input devices: " & CStr(nDevices)


Erase pRawInputDeviceList

RID(0).usUsagePage = &H1
RID(0).usUsage = &H6
RID(0).dwFlags = RIDEV_INPUTSINK
RID(0).hwnd = hwnd

If RegisterRawInputDevices(RID(0), 1, Len(RID(0))) = 0 Then
Debug.Print ("RawInput init failed.")
End If
End Sub

Public Function MainWndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long,
 ByVal lParam As Long) As Long

Static uniqueParaml As Long
Dim tmpx As Long, tmpy As Long
Dim raw As RAWINPUT
Dim lpb() As Byte
Dim dwSize As Long


If uMsg = WM_INPUT Then

counter = counter + 1
If (counter > 1) Then
Call GetRawInputData(lParam, RID_INPUT, ByVal 0&, dwSize, Len(raw.header))

ReDim lpb(dwSize - 1)

If GetRawInputData(lParam, RID_INPUT, lpb(0), dwSize, Len(raw.header)) <> dwSize Then
Debug.Print "GetRawInputData doesn't return correct size!"
End If

Call CopyMemory(raw, lpb(0), Len(raw))

Dim pcbSize As Long
Dim pData() As Byte
Dim i As Integer

Dim name As String
'Inicialize get Device Info
Call GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICENAME, ByVal 0&, pcbSize)

If (pcbSize > 0) Then
ReDim pData(pcbSize - 1)
Call GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICENAME, pData(0), pcbSize)
'Get Name of Device
For i = 1 To (pcbSize - 1) Step 1
If (pData(i) <> 0) Then
name = name & Chr(pData(i))
End If
Next i
End If

Dim array_device_name() As String

array_device_name = Split(name, "#")

If (array_device_name(1) = Device_Name) Then
If raw.header.dwType = RIM_TYPEKEYBOARD Then
txtBox.text = txtBox.text + Chr(raw.data.VKey)
End If
End If

counter = 0
End If
End If

MainWndProc = CallWindowProc(PrevWndProc, hwnd, uMsg, wParam, lParam)
End Function

Ahora la programación del formulario

' Formular Form1

Option Explicit
Private Sub Command1_Click()
Unload (Me)
End Sub
Private Sub Form_Load()
Call Module1.Init(Me.hwnd, Text1)
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Call Module1.Terminate
End Sub


Debo terminar el POST con el respectivo agradecimiento a la web:

http://foren.activevb.de/cgi-bin/foren/archivview.pl?forum=4&msg=381172&root=380881&page=1

La cual es la base de este código con las modificaciones para que lea un teclado la implementación inicial es para habilitar múltiples mouse.

jueves, 3 de junio de 2010

Netbeans Plataform LookUp + Visual Library + Property Sheet

Hola, este es un pequeño tutorial de como usar el netbenas plataform con su famosa libreria visual y el lookup (dificil de entender en un principio), bueno basicamente tratare de explicar el objetivo del proyecto:

Objetivo: Crear un Aplicacion Siute basada en Netbeans Plataform que tenga un entorno grafico ,que haga uso de LookUp API para la comunicacion entre componentes y la ventana de propiedades para visulizar las propiedades del Nodo.

Ok Empezemos.

Primero lo basico Crear un nuevo proyecto -> NetBeans Module -> NetBeans Platform Application

Ok le damos un nombre por ejemplo "Graph"

Creamos un modulo. para ello abrimos el arbol del proyecto en modulos -> click derecho y damos nuevo Modulo el nombre por ejemplo "Editor"

Ahora damos click derecho sobre el modulo propiedades -> Lebrerias
y agregamos las siguinetes dependencias qeu qeude de esta forma:





Abrimos el nodo de codigo y creamos 1 top componet dando click derecho nuevo Otro->ModuleDeveloped-> WindowComponent->WindowPosition en Editor y habilitamos el chek que dice open on aplication start

Le damos un nombre y le ponemos ejemplo "Visual Editor".

Agregamos en el formulario un BorderLayout y un ScrollPane que les quede de la siguiente forma:






Vamos al codigo fuente y escribimos lo siguiente en el constructor:


public VisualEditorTopComponent() {
initComponents();
setName(NbBundle.getMessage(VisualEditorTopComponent.class,"CTL_VisualEditorTopComponent"));
setToolTipText(NbBundle.getMessage(VisualEditorTopComponent.class,"HINT_VisualEditorTopComponent"));
//        setIcon(ImageUtilities.loadImage(ICON_PATH, true));
ScenaGrafica sg = new ScenaGrafica();
scrollpanel.setViewportView(sg.createView());
add(sg.createSatelliteView(), BorderLayout.WEST);
associateLookup(sg.getLookup());
}
              

Creamos una clase en el paquete que se llame ScenaGrafica.java y le ponemos el siguiente codigo:


/**
*
* @author ulmum
*/
public class ScenaGrafica extends GraphScene {

private Lookup lookup;
private InstanceContent content = new InstanceContent();
private LayerWidget capa_base = null;
private static int x = 10;
private static int y = 10;

public ScenaGrafica() {
capa_base = new LayerWidget(this);
addChild(capa_base);
addNode("Hola");
addNode("Luis");
addNode("Ulloa");
//Crea una bolsa abstracta
lookup = new AbstractLookup(content);
//getActions().addAction(ActionFactory.createSelectAction(new MySelectProvider()));

}

//Sobrescribe para que me de la bolsa que necesito
@Override
public Lookup getLookup() {
return lookup;
}

@Override
protected Widget attachNodeWidget(String node) {
LabelWidget widget = new LabelWidget(this, node);
widget.setPreferredLocation(new Point(x *= 2, y *= 2));
//crear movimiento al widget
widget.getActions().addAction(ActionFactory.createMoveAction());
//Click sobre el widget evento del raton
widget.getActions().addAction(new WidgetAction.Adapter() {

@Override
public State mouseClicked(Widget widget, WidgetMouseEvent event) {
if (event.getButton()!=1) {
   return State.REJECTED;
}
LabelWidget nodo = (LabelWidget) widget;
//Obtener el TopComponet
VisualEditorTopComponent tc = VisualEditorTopComponent.getDefault();
//Object obj= findObject(arg0);
//Crear el Nodo
miNodo nd = new miNodo(nodo);
//Ponerlo como activo en el topcomponent para que escuche la ventana de propiedades

tc.setActivatedNodes(new Node[]{nd});
//tc.set
//Mete a la bolsa el objeto y se modifica cuando se selecciona el objeto
content.set(Collections.singleton(nodo), null);
return State.CONSUMED;
}
});
//Crear la accion de seleccion cuando de click derecho del mouse
//widget.getActions().addAction(ActionFactory.createSelectAction(new SeleccionProveedor(), true));

//Agregar el widget a la capa base
//Dar el Borde
widget.setBorder(BorderFactory.createRoundedBorder(10, 5, Color.yellow, Color.blue));
capa_base.addChild(widget);

return widget;
}

@Override
protected Widget attachEdgeWidget(Object edge) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
protected void attachEdgeSourceAnchor(Object edge, String oldSourceNode, String sourceNode) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
protected void attachEdgeTargetAnchor(Object edge, String oldTargetNode, String targetNode) {
throw new UnsupportedOperationException("Not supported yet.");
}

private class SeleccionProveedor implements SelectProvider {

public boolean isAimingAllowed(Widget arg0, Point arg1, boolean arg2) {
return true;
}

public boolean isSelectionAllowed(Widget arg0, Point arg1, boolean arg2) {
return true;
}

/**
* Se ejecuta cuando se selecciona el widget
* @param arg0
* @param arg1
* @param arg2
*/
public void select(Widget arg0, Point arg1, boolean arg2) {

//Cast del widget a labelwidget
LabelWidget nodo = (LabelWidget) arg0;

VisualEditorTopComponent tc = VisualEditorTopComponent.getDefault();
//Object obj= findObject(arg0);

miNodo nd = new miNodo(nodo);
tc.setActivatedNodes(new Node[]{nd});
//tc.set
//Mete a la bolsa el objeto y se modifica cuando se selecciona el objeto
content.set(Collections.singleton(nodo), null);
}
}
}
          

Ahora creamos un topcomponet que va escuchar cuando cuando seleccionamos un nodo para ello crean un topcomponent y agregan un jlabel e impementan al topcomponete el LookupListener les debe quedar algo asi resumiendo:
public final class VisorTopComponent extends TopComponent implements LookupListener
          

Ahora escribimos el codigo del metodo componentOpened que se ejecuta cuando el componente abre y ponemos lo siguiente:
@SuppressWarnings("unchecked")
public void componentOpened() {
//tpl criterio de busqueda del Lookup en este caso como meti en la bolsa un LabelWidget busco por LabelWidget.class
Lookup.Template tpl = new Lookup.Template(LabelWidget.class);
//Buscar el bolsa global el criterio
result = Utilities.actionsGlobalContext().lookup(tpl);
//Registrar el evento que escucha cuando un objeto se mete a la bolsa o se saca se le asigna este mismo componete
result.addLookupListener(this);
}
          

Ha como nueva propiedad de la clase deben crear el result de la siguiente manera:

private Result result;
          


Ok ahora debemos escribir cuando el componente se cierra el metodo componentClosed


public void componentClosed() {
result.removeLookupListener(this);
result = null;
}
          


He implentamos el metodo que sobrescribe la intefaz LookUpListener

public void resultChanged(LookupEvent ev) {
//System.out.println(ev);
Lookup.Result r = (Lookup.Result) ev.getSource();
Collection c = r.allInstances();
//System.out.println("Tamanio de la coleccion " + c.size());
if (!c.isEmpty()) {
 LabelWidget o = (LabelWidget) c.iterator().next();
 jLabel1.setText(o.getLabel());
} else {
 jLabel1.setText("[no selection]");
 //Vaciar la ventana de propiedades del compenente Visual
 //VisualEditorTopComponent tc = VisualEditorTopComponent.getDefault();
 //Object obj= findObject(arg0);
 //tc.setActivatedNodes(new Node[]{Node.EMPTY});

}

}
          


Y la parte final creamos un clase miNodo.java que extiende la clase AbstractNode esto es para que mustre en la ventana de propiedades el objeto seleccionado ponemos el siguiente codigo

/**
*
* @author ulmum
* Mi Nodo es para usar la sheet properties
*/
public class miNodo extends AbstractNode {

public miNodo(LabelWidget widget) {
super(Children.LEAF,Lookups.singleton(widget));
setDisplayName("Propiedades del Nodo " + widget.getLabel());
}

public miNodo() {
super(Children.LEAF);
setDisplayName("Root");
}

@Override
protected Sheet createSheet() {
Sheet sheet = Sheet.createDefault();
Sheet.Set set = Sheet.createPropertiesSet();
LabelWidget obj = getLookup().lookup(LabelWidget.class);
try {
  Property label = new PropertySupport.Reflection(obj, String.class, "getLabel", null);
  label.setName("Nombre Etiqueta");
  set.put(label);
} catch (NoSuchMethodException ex) {
  ErrorManager.getDefault();
}

sheet.put(set);
return sheet;

}
}

          

Una vez hecho todo esto corremos y probamos si tienen alguna duda favor enviar sus comentarios adjunto el proyecto en zip para ser descargado
aqui

miércoles, 3 de febrero de 2010

Cargando un BMP byte a byte con JAVA

Prefacio
Este post está dedicado a entender como cargar un archivo BMP con java pero bueno a que viene eso, si ya hay librerías y APIs o métodos de la librería swing que hacen este trabajo sucio. Pues bueno me interese en saber como haría para cargar esta imagen byte a byte de un fichero almacenado, para después cargar una imagen en un LCD de un celular (eso es para después), bueno la lógica es la misma creo en los diferentes lenguajes.

LinkGrafia
http://es.wikipedia.org/wiki/BMP
http://carlosagreda.googlepages.com/bmp.html
http://elblogdelfrasco.blogspot.com/2008/06/java-nivel-de-bits.html

Que se necesita
1. Netbeans 5.5 o mayor.

Empezamos

Bueno los primeros 54 bytes de todo archivo BMP son de la metadata (Información del Fichero) dicha información la encontrar en los 2 link que os pongo a disposición.
Bueno a mi me sirvieron los Bytes que conforman el alto y ancho de la imagen.

A Continuación les pongo el fragmento de código que permite leer los 54 bytes para sacara el ancho alto y tamaño de la imagen.




Es hora de explicar esto:

(datos[i] & 0xff)



Bueno eso es nada más que una operación lógica a nivel de bits por ejemplo si en binario seria:


1 Byte 2 Byte 3 Byte 4 Byte Hexadecimal Decimal
00000000 00000000 00000000 01111110 0x7E 126
Aplico el operador &
11111111 11111111 11111111 11111111 0xFF 255
Resultado
00000000 00000000 00000000 01111110 0X7E 126


Como se observa no pasa nada e incluso es un poco innecesario pero al momento de leer los bytes del fichero el método read inserta en el vector valores negativos por lo cual se la aplica la máscara para que devuelva el valor real del número.

Segundo ahora a que viene el símbolo <<
((long)(datos[2] & 0xff))<<bite

Bueno esto es una operación de desplazamiento que lo que hará es que el resultado anterior moverlo 0, 8, 16 y 24 posiciones si quisiera mover 8 bits a la izquierda seria así:

byte1=00000000.00000000.0000000.11100111
byte2=00000000.00000000.1111101.00000000
byte3=00000000.00000010.0000000.00000000
byte4=10111101.00000000.0000000.00000000
byte1 | byte2 | byte3 | byte4
Resultado
byte=10111101.00000010.1111101.11100111 = 5E817DE7 = 1585544679 Bytes


bueno lo del (long) esta demás pero no es nada más que un casting de tipos de datos ahora así como unimos los bytes. lo haremos usando el operador | de operación lógica de bits. Resumiendo


Uffff larga explicación... solo para el inicio bueno todo esto se pude resumir practicando y usando un ciclo for.

Bueno una vez sacado los datos de la meta data nos queda nada más que hacer 2 for para recorrer las filas y columnas, leer los bytes que nos quedan de 3 en 3 ya que ese el estándar RGB el primer byte es el ROJO(R), el segundo el VERDE(G) y el Tercero el AZUL(B) quedando así (255,255,255) y por ultimo sobrescribir el método paint de un formulario swing para graficar el pixel basta con poner:
g2d.drawRect(x,y,1,1)
Le pones de 1 de ancho por 1 de alto hay el pixel el código es el siguiente:



La variable resto son bytes sobrantes que debe calcularse en el bmp y leer estos bytes restantes para que no se descuadre a imagen.

Nota: el for de las filas empieza al revés por que se almacenan de abajo hacia arriba.

Descarga el Proyecto

Con Nuevo Blog ...

Esmpezando el 2010 y migro de blog mas que todo lo hize por usar el svn de google y estaba arto de tanto spam en mi cuenta de gmail.... voy a recuperar mis post anteriores antes que los borren definitivamente