Vamos a programar #17 - Extraer una imagen embebida en un MP3
Hola a todos de nuevo. El día de hoy vamos a terminar con el temas de las imágenes embebidas en los archivos MP3.
En el post anterior, hicimos una parte del código de C# encargado de hacer la extracción. Había quedado pendiente el trabajo para la versión 2 de las etiquetas ID3.
Hay que recordar que la esctructura del la etiqueta "PIC" es la siguiente:
En el post anterior, hicimos una parte del código de C# encargado de hacer la extracción. Había quedado pendiente el trabajo para la versión 2 de las etiquetas ID3.
Hay que recordar que la esctructura del la etiqueta "PIC" es la siguiente:
Attached picture "PIC"
Frame size $xx xx xx
Text encoding $xx
Image format $xx xx xx
Picture type $xx
Description <textstring> $00 (00)
Picture data <binary data>
Basados en la información anterior crearemos el código necesario.
El código para la versión 2.
Retomando el codigo anterior, solo hay que agregar lo que nos hace falta. La función ImageContent constaba de 3 condiciones if importantes (ademas de algunos secundarios), el primero y principal consiste en verficar si hay una etiqueta ID3 valida, si la había, el siguiente if comprobaba que la version fuera la 2.3, el siguiente comprobaba para la version 2. Está fue la que quedo pendiente, el siguiente codigo va inmediatamente despues del if que comprobaba para la version 2.3.
if (MyTagType == TagVersion.TagVer22) { { //PIC BinRead.BaseStream.Position = PicTagPos + 3; //Tamaño TotalLenght = TotalLenght + BinRead.ReadByte() * 256 * 256; TotalLenght = TotalLenght + BinRead.ReadByte() * 256; TotalLenght = TotalLenght + BinRead.ReadByte(); txtInfo.Text = txtInfo.Text + "\n La etiqueta PIC esta en la dirección: " + PicTagPos.ToString() + "\n"; txtInfo.Text = txtInfo.Text + "con longitud de" + TotalLenght.ToString() + " bytes\n"; //TextEncoding BinRead.ReadByte(); //Type JPG o PNG string MType = ""; MType = MType + string.Concat((char)BinRead.ReadByte()); MType = MType + string.Concat((char)BinRead.ReadByte()); MType = MType + string.Concat((char)BinRead.ReadByte()); txtInfo.Text = txtInfo.Text + "\nDel tipo " + MType; //Tipo de imagen BinRead.ReadByte(); //Reciclamos el flag anterior IsNotZero = true; string ImgDescription = ""; //Descripcion de la imagen while (IsNotZero == false) { byte Val = BinRead.ReadByte(); if (Val != 0x00) { ImgDescription = ImgDescription + string.Concat((char)Val); IsNotZero = false; } else { IsNotZero = true; } } long ImageFileBegin = BinRead.BaseStream.Position; int ImageLenght = (TotalLenght - 1 - ((int)ImageFileBegin - PicTagPos - 6)); txtInfo.Text = txtInfo.Text + " La imagen empieza en " + ImageFileBegin.ToString(); txtInfo.Text = txtInfo.Text + "Y mide " + ImageLenght.ToString(); //Creamos una imagen desde el stream y la asignamos al picbox //Ponemos el puntero al inicio de la imagen BinRead.BaseStream.Position = ImageFileBegin + 1; using (MemoryStream MS = new MemoryStream(BinRead.ReadBytes(ImageLenght))) { PicArt.Image = Image.FromStream(MS); using (FileStream file = new FileStream(SaveLocation + "." + ImageType(MType), FileMode.Create, FileAccess.Write)) { MS.WriteTo(file); file.Flush(); file.Close(); } MS.Close(); } } } }
Si revisamos el código de forma detenida veremos que es mu similar al código anterior. Entonces te preguntarás ¿No es un desperdicio? Si y no, el código está pensado para hacer una demostración de lo que hicimos en el primer post? Y la respuesta es: NO, lo que trate de hacer con estos post es demostrar como es que se puede portar una situación al código así "tal cual", porque de hecho lo que hicimos aquí, fue lo mismo que hicimos con el programa XVI32. Es decir lo que primero hicimos a mano, luego lo plasmamos en el código.
En el próximo post crearemos una función para procesar por lotes y liberaré la aplicación completa, por ahora es todo.
Los leo luego.
Información para una canción con etiqueta PIC (Ver 2) |
Información para una canción con etiqueta APIC (Ver 2.3 {Lo admito soy un Pokefan!!!}) |
Los leo luego.
I had some issues with the code.
ResponderBorrar